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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/extension_service.h" 6 7 #include <algorithm> 8 #include <iterator> 9 #include <set> 10 11 #include "base/basictypes.h" 12 #include "base/bind.h" 13 #include "base/callback.h" 14 #include "base/command_line.h" 15 #include "base/file_util.h" 16 #include "base/logging.h" 17 #include "base/metrics/histogram.h" 18 #include "base/prefs/pref_service.h" 19 #include "base/stl_util.h" 20 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_util.h" 22 #include "base/strings/stringprintf.h" 23 #include "base/strings/utf_string_conversions.h" 24 #include "base/threading/sequenced_worker_pool.h" 25 #include "base/threading/thread_restrictions.h" 26 #include "base/time/time.h" 27 #include "base/values.h" 28 #include "base/version.h" 29 #include "chrome/browser/browser_process.h" 30 #include "chrome/browser/chrome_notification_types.h" 31 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 32 #include "chrome/browser/extensions/api/storage/settings_frontend.h" 33 #include "chrome/browser/extensions/component_loader.h" 34 #include "chrome/browser/extensions/crx_installer.h" 35 #include "chrome/browser/extensions/data_deleter.h" 36 #include "chrome/browser/extensions/extension_disabled_ui.h" 37 #include "chrome/browser/extensions/extension_error_reporter.h" 38 #include "chrome/browser/extensions/extension_error_ui.h" 39 #include "chrome/browser/extensions/extension_host.h" 40 #include "chrome/browser/extensions/extension_install_ui.h" 41 #include "chrome/browser/extensions/extension_special_storage_policy.h" 42 #include "chrome/browser/extensions/extension_sync_service.h" 43 #include "chrome/browser/extensions/extension_system.h" 44 #include "chrome/browser/extensions/external_install_ui.h" 45 #include "chrome/browser/extensions/external_provider_impl.h" 46 #include "chrome/browser/extensions/install_verifier.h" 47 #include "chrome/browser/extensions/installed_loader.h" 48 #include "chrome/browser/extensions/permissions_updater.h" 49 #include "chrome/browser/extensions/unpacked_installer.h" 50 #include "chrome/browser/extensions/updater/extension_updater.h" 51 #include "chrome/browser/profiles/profile.h" 52 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 53 #include "chrome/browser/ui/webui/favicon_source.h" 54 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" 55 #include "chrome/browser/ui/webui/theme_source.h" 56 #include "chrome/common/chrome_switches.h" 57 #include "chrome/common/crash_keys.h" 58 #include "chrome/common/extensions/extension_constants.h" 59 #include "chrome/common/extensions/extension_file_util.h" 60 #include "chrome/common/extensions/extension_messages.h" 61 #include "chrome/common/extensions/features/feature_channel.h" 62 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" 63 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 64 #include "chrome/common/extensions/manifest_url_handler.h" 65 #include "chrome/common/pref_names.h" 66 #include "chrome/common/url_constants.h" 67 #include "components/startup_metric_utils/startup_metric_utils.h" 68 #include "content/public/browser/browser_thread.h" 69 #include "content/public/browser/devtools_agent_host.h" 70 #include "content/public/browser/notification_service.h" 71 #include "content/public/browser/notification_types.h" 72 #include "content/public/browser/render_process_host.h" 73 #include "content/public/browser/site_instance.h" 74 #include "content/public/browser/storage_partition.h" 75 #include "content/public/browser/url_data_source.h" 76 #include "extensions/browser/app_sorting.h" 77 #include "extensions/browser/event_router.h" 78 #include "extensions/browser/extensions_browser_client.h" 79 #include "extensions/browser/external_provider_interface.h" 80 #include "extensions/browser/management_policy.h" 81 #include "extensions/browser/pending_extension_manager.h" 82 #include "extensions/browser/process_manager.h" 83 #include "extensions/browser/update_observer.h" 84 #include "extensions/common/constants.h" 85 #include "extensions/common/error_utils.h" 86 #include "extensions/common/extension.h" 87 #include "extensions/common/extensions_client.h" 88 #include "extensions/common/feature_switch.h" 89 #include "extensions/common/manifest.h" 90 #include "extensions/common/manifest_constants.h" 91 #include "extensions/common/manifest_handlers/background_info.h" 92 #include "extensions/common/manifest_handlers/incognito_info.h" 93 #include "extensions/common/manifest_handlers/shared_module_info.h" 94 #include "extensions/common/permissions/permission_message_provider.h" 95 #include "extensions/common/permissions/permissions_data.h" 96 #include "grit/generated_resources.h" 97 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 98 #include "ui/base/webui/web_ui_util.h" 99 #include "url/gurl.h" 100 #include "webkit/browser/database/database_tracker.h" 101 #include "webkit/browser/database/database_util.h" 102 103 #if defined(OS_CHROMEOS) 104 #include "chrome/browser/chromeos/extensions/install_limiter.h" 105 #include "webkit/browser/fileapi/file_system_backend.h" 106 #include "webkit/browser/fileapi/file_system_context.h" 107 #endif 108 109 using content::BrowserContext; 110 using content::BrowserThread; 111 using content::DevToolsAgentHost; 112 using extensions::CrxInstaller; 113 using extensions::Extension; 114 using extensions::ExtensionIdSet; 115 using extensions::ExtensionInfo; 116 using extensions::FeatureSwitch; 117 using extensions::InstallVerifier; 118 using extensions::ManagementPolicy; 119 using extensions::Manifest; 120 using extensions::PermissionMessage; 121 using extensions::PermissionMessages; 122 using extensions::PermissionSet; 123 using extensions::SharedModuleInfo; 124 using extensions::UnloadedExtensionInfo; 125 126 namespace errors = extensions::manifest_errors; 127 128 namespace { 129 130 // Histogram values for logging events related to externally installed 131 // extensions. 132 enum ExternalExtensionEvent { 133 EXTERNAL_EXTENSION_INSTALLED = 0, 134 EXTERNAL_EXTENSION_IGNORED, 135 EXTERNAL_EXTENSION_REENABLED, 136 EXTERNAL_EXTENSION_UNINSTALLED, 137 EXTERNAL_EXTENSION_BUCKET_BOUNDARY, 138 }; 139 140 // Prompt the user this many times before considering an extension acknowledged. 141 static const int kMaxExtensionAcknowledgePromptCount = 3; 142 143 // Wait this many seconds after an extensions becomes idle before updating it. 144 static const int kUpdateIdleDelay = 5; 145 146 // Wait this many seconds before trying to garbage collect extensions again. 147 static const int kGarbageCollectRetryDelay = 30; 148 149 // Wait this many seconds after startup to see if there are any extensions 150 // which can be garbage collected. 151 static const int kGarbageCollectStartupDelay = 30; 152 153 static bool IsSharedModule(const Extension* extension) { 154 return SharedModuleInfo::IsSharedModule(extension); 155 } 156 157 static bool IsCWSSharedModule(const Extension* extension) { 158 return extension->from_webstore() && IsSharedModule(extension); 159 } 160 161 class SharedModuleProvider : public extensions::ManagementPolicy::Provider { 162 public: 163 SharedModuleProvider() {} 164 virtual ~SharedModuleProvider() {} 165 166 virtual std::string GetDebugPolicyProviderName() const OVERRIDE { 167 return "SharedModuleProvider"; 168 } 169 170 virtual bool UserMayModifySettings(const Extension* extension, 171 base::string16* error) const OVERRIDE { 172 return !IsCWSSharedModule(extension); 173 } 174 175 virtual bool MustRemainEnabled(const Extension* extension, 176 base::string16* error) const OVERRIDE { 177 return IsCWSSharedModule(extension); 178 } 179 180 private: 181 DISALLOW_COPY_AND_ASSIGN(SharedModuleProvider); 182 }; 183 184 enum VerifyAllSuccess { 185 VERIFY_ALL_BOOTSTRAP_SUCCESS = 0, 186 VERIFY_ALL_BOOTSTRAP_FAILURE, 187 VERIFY_ALL_NON_BOOTSTRAP_SUCCESS, 188 VERIFY_ALL_NON_BOOTSTRAP_FAILURE, 189 190 // Used in histograms. Do not remove/reorder any entries above, and the below 191 // MAX entry should always come last. 192 193 VERIFY_ALL_SUCCESS_MAX 194 }; 195 196 void LogVerifyAllSuccessHistogram(bool bootstrap, bool success) { 197 VerifyAllSuccess result; 198 if (bootstrap && success) 199 result = VERIFY_ALL_BOOTSTRAP_SUCCESS; 200 else if (bootstrap && !success) 201 result = VERIFY_ALL_BOOTSTRAP_FAILURE; 202 else if (!bootstrap && success) 203 result = VERIFY_ALL_NON_BOOTSTRAP_SUCCESS; 204 else 205 result = VERIFY_ALL_NON_BOOTSTRAP_FAILURE; 206 207 UMA_HISTOGRAM_ENUMERATION("ExtensionService.VerifyAllSuccess", 208 result, VERIFY_ALL_SUCCESS_MAX); 209 } 210 211 void LogAddVerifiedSuccess(bool success) { 212 UMA_HISTOGRAM_BOOLEAN("ExtensionService.AddVerified", success); 213 } 214 215 } // namespace 216 217 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() 218 : background_page_ready(false), 219 being_upgraded(false), 220 has_used_webrequest(false) { 221 } 222 223 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { 224 } 225 226 // ExtensionService. 227 228 void ExtensionService::CheckExternalUninstall(const std::string& id) { 229 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 230 231 // Check if the providers know about this extension. 232 extensions::ProviderCollection::const_iterator i; 233 for (i = external_extension_providers_.begin(); 234 i != external_extension_providers_.end(); ++i) { 235 DCHECK(i->get()->IsReady()); 236 if (i->get()->HasExtension(id)) 237 return; // Yup, known extension, don't uninstall. 238 } 239 240 // We get the list of external extensions to check from preferences. 241 // It is possible that an extension has preferences but is not loaded. 242 // For example, an extension that requires experimental permissions 243 // will not be loaded if the experimental command line flag is not used. 244 // In this case, do not uninstall. 245 if (!GetInstalledExtension(id)) { 246 // We can't call UninstallExtension with an unloaded/invalid 247 // extension ID. 248 LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension " 249 << "with id: " << id; 250 return; 251 } 252 UninstallExtension(id, true, NULL); 253 } 254 255 void ExtensionService::SetFileTaskRunnerForTesting( 256 base::SequencedTaskRunner* task_runner) { 257 file_task_runner_ = task_runner; 258 } 259 260 void ExtensionService::ClearProvidersForTesting() { 261 external_extension_providers_.clear(); 262 } 263 264 void ExtensionService::AddProviderForTesting( 265 extensions::ExternalProviderInterface* test_provider) { 266 CHECK(test_provider); 267 external_extension_providers_.push_back( 268 linked_ptr<extensions::ExternalProviderInterface>(test_provider)); 269 } 270 271 bool ExtensionService::OnExternalExtensionUpdateUrlFound( 272 const std::string& id, 273 const GURL& update_url, 274 Manifest::Location location, 275 int creation_flags, 276 bool mark_acknowledged) { 277 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 278 CHECK(Extension::IdIsValid(id)); 279 280 const Extension* extension = GetExtensionById(id, true); 281 if (extension) { 282 // Already installed. Skip this install if the current location has 283 // higher priority than |location|. 284 Manifest::Location current = extension->location(); 285 if (current == Manifest::GetHigherPriorityLocation(current, location)) 286 return false; 287 // Otherwise, overwrite the current installation. 288 } 289 290 // Add |id| to the set of pending extensions. If it can not be added, 291 // then there is already a pending record from a higher-priority install 292 // source. In this case, signal that this extension will not be 293 // installed by returning false. 294 if (!pending_extension_manager()->AddFromExternalUpdateUrl( 295 id, update_url, location, creation_flags, mark_acknowledged)) { 296 return false; 297 } 298 299 update_once_all_providers_are_ready_ = true; 300 return true; 301 } 302 303 const Extension* ExtensionService::GetInstalledExtensionByUrl( 304 const GURL& url) const { 305 return extensions_.GetExtensionOrAppByURL(url); 306 } 307 308 const Extension* ExtensionService::GetInstalledApp(const GURL& url) const { 309 const Extension* extension = GetInstalledExtensionByUrl(url); 310 return (extension && extension->is_app()) ? extension : NULL; 311 } 312 313 bool ExtensionService::IsInstalledApp(const GURL& url) const { 314 return !!GetInstalledApp(url); 315 } 316 317 // static 318 // This function is used to implement the command-line switch 319 // --uninstall-extension, and to uninstall an extension via sync. The LOG 320 // statements within this function are used to inform the user if the uninstall 321 // cannot be done. 322 bool ExtensionService::UninstallExtensionHelper( 323 ExtensionService* extensions_service, 324 const std::string& extension_id) { 325 // We can't call UninstallExtension with an invalid extension ID. 326 if (!extensions_service->GetInstalledExtension(extension_id)) { 327 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " 328 << "id: " << extension_id; 329 return false; 330 } 331 332 // The following call to UninstallExtension will not allow an uninstall of a 333 // policy-controlled extension. 334 base::string16 error; 335 if (!extensions_service->UninstallExtension(extension_id, false, &error)) { 336 LOG(WARNING) << "Cannot uninstall extension with id " << extension_id 337 << ": " << error; 338 return false; 339 } 340 341 return true; 342 } 343 344 ExtensionService::ExtensionService(Profile* profile, 345 const CommandLine* command_line, 346 const base::FilePath& install_directory, 347 extensions::ExtensionPrefs* extension_prefs, 348 extensions::Blacklist* blacklist, 349 bool autoupdate_enabled, 350 bool extensions_enabled, 351 extensions::OneShotEvent* ready) 352 : extensions::Blacklist::Observer(blacklist), 353 profile_(profile), 354 system_(extensions::ExtensionSystem::Get(profile)), 355 extension_prefs_(extension_prefs), 356 blacklist_(blacklist), 357 settings_frontend_(extensions::SettingsFrontend::Create(profile)), 358 extension_sync_service_(NULL), 359 pending_extension_manager_(*this), 360 install_directory_(install_directory), 361 extensions_enabled_(extensions_enabled), 362 show_extensions_prompts_(true), 363 install_updates_when_idle_(true), 364 ready_(ready), 365 update_once_all_providers_are_ready_(false), 366 browser_terminating_(false), 367 installs_delayed_for_gc_(false), 368 is_first_run_(false) { 369 #if defined(OS_CHROMEOS) 370 disable_garbage_collection_ = false; 371 #endif 372 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 373 374 // Figure out if extension installation should be enabled. 375 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( 376 *command_line, profile)) 377 extensions_enabled_ = false; 378 379 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 380 content::NotificationService::AllBrowserContextsAndSources()); 381 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, 382 content::NotificationService::AllBrowserContextsAndSources()); 383 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, 384 content::NotificationService::AllBrowserContextsAndSources()); 385 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 386 content::NotificationService::AllBrowserContextsAndSources()); 387 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, 388 content::NotificationService::AllBrowserContextsAndSources()); 389 pref_change_registrar_.Init(profile->GetPrefs()); 390 base::Closure callback = 391 base::Bind(&ExtensionService::OnExtensionInstallPrefChanged, 392 base::Unretained(this)); 393 pref_change_registrar_.Add(prefs::kExtensionInstallAllowList, callback); 394 pref_change_registrar_.Add(prefs::kExtensionInstallDenyList, callback); 395 pref_change_registrar_.Add(prefs::kExtensionAllowedTypes, callback); 396 397 // Set up the ExtensionUpdater 398 if (autoupdate_enabled) { 399 int update_frequency = extensions::kDefaultUpdateFrequencySeconds; 400 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { 401 base::StringToInt(command_line->GetSwitchValueASCII( 402 switches::kExtensionsUpdateFrequency), 403 &update_frequency); 404 } 405 updater_.reset(new extensions::ExtensionUpdater(this, 406 extension_prefs, 407 profile->GetPrefs(), 408 profile, 409 update_frequency)); 410 } 411 412 component_loader_.reset( 413 new extensions::ComponentLoader(this, 414 profile->GetPrefs(), 415 g_browser_process->local_state())); 416 417 if (extensions_enabled_) { 418 extensions::ExternalProviderImpl::CreateExternalProviders( 419 this, profile_, &external_extension_providers_); 420 } 421 422 // Set this as the ExtensionService for app sorting to ensure it causes syncs 423 // if required. 424 is_first_run_ = !extension_prefs_->SetAlertSystemFirstRun(); 425 426 #if defined(ENABLE_EXTENSIONS) 427 extension_action_storage_manager_.reset( 428 new extensions::ExtensionActionStorageManager(profile_)); 429 #endif 430 431 shared_module_policy_provider_.reset(new SharedModuleProvider); 432 433 // How long is the path to the Extensions directory? 434 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.ExtensionRootPathLength", 435 install_directory_.value().length(), 0, 500, 100); 436 } 437 438 const ExtensionSet* ExtensionService::extensions() const { 439 return &extensions_; 440 } 441 442 const ExtensionSet* ExtensionService::disabled_extensions() const { 443 return &disabled_extensions_; 444 } 445 446 const ExtensionSet* ExtensionService::terminated_extensions() const { 447 return &terminated_extensions_; 448 } 449 450 const ExtensionSet* ExtensionService::blacklisted_extensions() const { 451 return &blacklisted_extensions_; 452 } 453 454 const ExtensionSet* ExtensionService::delayed_installs() const { 455 return &delayed_installs_; 456 } 457 458 scoped_ptr<ExtensionSet> 459 ExtensionService::GenerateInstalledExtensionsSet() const { 460 scoped_ptr<ExtensionSet> installed_extensions(new ExtensionSet()); 461 installed_extensions->InsertAll(extensions_); 462 installed_extensions->InsertAll(disabled_extensions_); 463 installed_extensions->InsertAll(terminated_extensions_); 464 installed_extensions->InsertAll(blacklisted_extensions_); 465 return installed_extensions.PassAs<ExtensionSet>(); 466 } 467 468 extensions::PendingExtensionManager* 469 ExtensionService::pending_extension_manager() { 470 return &pending_extension_manager_; 471 } 472 473 ExtensionService::~ExtensionService() { 474 // No need to unload extensions here because they are profile-scoped, and the 475 // profile is in the process of being deleted. 476 477 extensions::ProviderCollection::const_iterator i; 478 for (i = external_extension_providers_.begin(); 479 i != external_extension_providers_.end(); ++i) { 480 extensions::ExternalProviderInterface* provider = i->get(); 481 provider->ServiceShutdown(); 482 } 483 } 484 485 void ExtensionService::Shutdown() { 486 system_->management_policy()->UnregisterProvider( 487 shared_module_policy_provider_.get()); 488 } 489 490 const Extension* ExtensionService::GetExtensionById( 491 const std::string& id, bool include_disabled) const { 492 int include_mask = INCLUDE_ENABLED; 493 if (include_disabled) { 494 // Include blacklisted extensions here because there are hundreds of 495 // callers of this function, and many might assume that this includes those 496 // that have been disabled due to blacklisting. 497 include_mask |= INCLUDE_DISABLED | INCLUDE_BLACKLISTED; 498 } 499 return GetExtensionById(id, include_mask); 500 } 501 502 GURL ExtensionService::GetSiteForExtensionId(const std::string& extension_id) { 503 return content::SiteInstance::GetSiteForURL( 504 profile_, 505 Extension::GetBaseURLFromExtensionId(extension_id)); 506 } 507 508 const Extension* ExtensionService::GetExtensionById( 509 const std::string& id, int include_mask) const { 510 std::string lowercase_id = StringToLowerASCII(id); 511 if (include_mask & INCLUDE_ENABLED) { 512 const Extension* extension = extensions_.GetByID(lowercase_id); 513 if (extension) 514 return extension; 515 } 516 if (include_mask & INCLUDE_DISABLED) { 517 const Extension* extension = disabled_extensions_.GetByID(lowercase_id); 518 if (extension) 519 return extension; 520 } 521 if (include_mask & INCLUDE_TERMINATED) { 522 const Extension* extension = terminated_extensions_.GetByID(lowercase_id); 523 if (extension) 524 return extension; 525 } 526 if (include_mask & INCLUDE_BLACKLISTED) { 527 const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id); 528 if (extension) 529 return extension; 530 } 531 return NULL; 532 } 533 534 void ExtensionService::Init() { 535 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 536 537 base::Time begin_time = base::Time::Now(); 538 539 DCHECK(!is_ready()); // Can't redo init. 540 DCHECK_EQ(extensions_.size(), 0u); 541 542 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 543 if (cmd_line->HasSwitch(switches::kInstallFromWebstore) || 544 cmd_line->HasSwitch(switches::kLimitedInstallFromWebstore)) { 545 // The sole purpose of this launch is to install a new extension from CWS 546 // and immediately terminate: loading already installed extensions is 547 // unnecessary and may interfere with the inline install dialog (e.g. if an 548 // extension listens to onStartup and opens a window). 549 SetReadyAndNotifyListeners(); 550 } else { 551 // LoadAllExtensions() calls OnLoadedInstalledExtensions(). 552 component_loader_->LoadAll(); 553 extensions::InstalledLoader(this).LoadAllExtensions(); 554 555 ReconcileKnownDisabled(); 556 557 // Attempt to re-enable extensions whose only disable reason is reloading. 558 std::vector<std::string> extensions_to_enable; 559 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); 560 iter != disabled_extensions_.end(); ++iter) { 561 const Extension* e = iter->get(); 562 if (extension_prefs_->GetDisableReasons(e->id()) == 563 Extension::DISABLE_RELOAD) { 564 extensions_to_enable.push_back(e->id()); 565 } 566 } 567 for (std::vector<std::string>::iterator it = extensions_to_enable.begin(); 568 it != extensions_to_enable.end(); ++it) { 569 EnableExtension(*it); 570 } 571 572 // Finish install (if possible) of extensions that were still delayed while 573 // the browser was shut down. 574 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info( 575 extension_prefs_->GetAllDelayedInstallInfo()); 576 for (size_t i = 0; i < delayed_info->size(); ++i) { 577 ExtensionInfo* info = delayed_info->at(i).get(); 578 scoped_refptr<const Extension> extension(NULL); 579 if (info->extension_manifest) { 580 std::string error; 581 extension = Extension::Create( 582 info->extension_path, 583 info->extension_location, 584 *info->extension_manifest, 585 extension_prefs_->GetDelayedInstallCreationFlags( 586 info->extension_id), 587 info->extension_id, 588 &error); 589 if (extension.get()) 590 delayed_installs_.Insert(extension); 591 } 592 } 593 MaybeFinishDelayedInstallations(); 594 595 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2( 596 extension_prefs_->GetAllDelayedInstallInfo()); 597 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", 598 delayed_info2->size() - delayed_info->size()); 599 600 SetReadyAndNotifyListeners(); 601 602 // TODO(erikkay) this should probably be deferred to a future point 603 // rather than running immediately at startup. 604 CheckForExternalUpdates(); 605 606 MaybeBootstrapVerifier(); 607 608 base::MessageLoop::current()->PostDelayedTask( 609 FROM_HERE, 610 base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()), 611 base::TimeDelta::FromSeconds(kGarbageCollectStartupDelay)); 612 613 if (extension_prefs_->NeedsStorageGarbageCollection()) { 614 GarbageCollectIsolatedStorage(); 615 extension_prefs_->SetNeedsStorageGarbageCollection(false); 616 } 617 system_->management_policy()->RegisterProvider( 618 shared_module_policy_provider_.get()); 619 } 620 621 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", 622 base::Time::Now() - begin_time); 623 } 624 625 void ExtensionService::MaybeBootstrapVerifier() { 626 InstallVerifier* verifier = 627 extensions::ExtensionSystem::Get(profile_)->install_verifier(); 628 bool do_bootstrap = false; 629 630 if (verifier->NeedsBootstrap()) { 631 do_bootstrap = true; 632 } else { 633 // If any of the installed extensions have an install time newer than the 634 // signature's timestamp, we need to bootstrap because our signature may 635 // be missing valid extensions. 636 base::Time timestamp = verifier->SignatureTimestamp(); 637 scoped_ptr<ExtensionSet> extensions = GenerateInstalledExtensionsSet(); 638 for (ExtensionSet::const_iterator i = extensions->begin(); 639 i != extensions->end(); 640 ++i) { 641 const Extension& extension = **i; 642 base::Time install_time = 643 extension_prefs_->GetInstallTime(extension.id()); 644 if (verifier->NeedsVerification(extension) && 645 install_time < base::Time::Now() && install_time >= timestamp) { 646 do_bootstrap = true; 647 break; 648 } 649 } 650 } 651 if (do_bootstrap) 652 VerifyAllExtensions(true); // bootstrap=true. 653 } 654 655 void ExtensionService::VerifyAllExtensions(bool bootstrap) { 656 ExtensionIdSet to_add; 657 scoped_ptr<ExtensionSet> all_extensions = GenerateInstalledExtensionsSet(); 658 659 for (ExtensionSet::const_iterator i = all_extensions->begin(); 660 i != all_extensions->end(); ++i) { 661 const Extension& extension = **i; 662 663 if (InstallVerifier::NeedsVerification(extension)) 664 to_add.insert(extension.id()); 665 } 666 extensions::ExtensionSystem::Get(profile_)->install_verifier()->AddMany( 667 to_add, base::Bind(&ExtensionService::FinishVerifyAllExtensions, 668 AsWeakPtr(), bootstrap)); 669 } 670 671 void ExtensionService::FinishVerifyAllExtensions(bool bootstrap, bool success) { 672 LogVerifyAllSuccessHistogram(bootstrap, success); 673 if (success) { 674 // Check to see if any currently unverified extensions became verified. 675 InstallVerifier* verifier = 676 extensions::ExtensionSystem::Get(profile_)->install_verifier(); 677 for (ExtensionSet::const_iterator i = disabled_extensions_.begin(); 678 i != disabled_extensions_.end(); ++i) { 679 const Extension& extension = **i; 680 int disable_reasons = extension_prefs_->GetDisableReasons(extension.id()); 681 if (disable_reasons & Extension::DISABLE_NOT_VERIFIED && 682 !verifier->MustRemainDisabled(&extension, NULL, NULL)) { 683 extension_prefs_->RemoveDisableReason(extension.id(), 684 Extension::DISABLE_NOT_VERIFIED); 685 // Notify interested observers (eg the extensions settings page) by 686 // sending an UNLOADED notification. 687 // 688 // TODO(asargent) - this is a slight hack because it's already 689 // disabled; the right solution might be to add a separate listener 690 // interface for DisableReason's changing. http://crbug.com/328916 691 UnloadedExtensionInfo details(&extension, 692 UnloadedExtensionInfo::REASON_DISABLE); 693 content::NotificationService::current()->Notify( 694 chrome::NOTIFICATION_EXTENSION_UNLOADED, 695 content::Source<Profile>(profile_), 696 content::Details<UnloadedExtensionInfo>(&details)); 697 } 698 } 699 // Might disable some extensions. 700 CheckManagementPolicy(); 701 } 702 } 703 704 bool ExtensionService::UpdateExtension(const std::string& id, 705 const base::FilePath& extension_path, 706 const GURL& download_url, 707 CrxInstaller** out_crx_installer) { 708 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 709 if (browser_terminating_) { 710 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; 711 // Leak the temp file at extension_path. We don't want to add to the disk 712 // I/O burden at shutdown, we can't rely on the I/O completing anyway, and 713 // the file is in the OS temp directory which should be cleaned up for us. 714 return false; 715 } 716 717 const extensions::PendingExtensionInfo* pending_extension_info = 718 pending_extension_manager()->GetById(id); 719 720 const Extension* extension = GetInstalledExtension(id); 721 if (!pending_extension_info && !extension) { 722 LOG(WARNING) << "Will not update extension " << id 723 << " because it is not installed or pending"; 724 // Delete extension_path since we're not creating a CrxInstaller 725 // that would do it for us. 726 if (!GetFileTaskRunner()->PostTask( 727 FROM_HERE, 728 base::Bind( 729 &extension_file_util::DeleteFile, extension_path, false))) 730 NOTREACHED(); 731 732 return false; 733 } 734 735 // We want a silent install only for non-pending extensions and 736 // pending extensions that have install_silently set. 737 scoped_ptr<ExtensionInstallPrompt> client; 738 if (pending_extension_info && !pending_extension_info->install_silently()) 739 client.reset(ExtensionInstallUI::CreateInstallPromptWithProfile(profile_)); 740 741 scoped_refptr<CrxInstaller> installer( 742 CrxInstaller::Create(this, client.Pass())); 743 installer->set_expected_id(id); 744 int creation_flags = Extension::NO_FLAGS; 745 if (pending_extension_info) { 746 installer->set_install_source(pending_extension_info->install_source()); 747 if (pending_extension_info->install_silently()) 748 installer->set_allow_silent_install(true); 749 creation_flags = pending_extension_info->creation_flags(); 750 if (pending_extension_info->mark_acknowledged()) 751 AcknowledgeExternalExtension(id); 752 } else if (extension) { 753 installer->set_install_source(extension->location()); 754 } 755 // If the extension was installed from or has migrated to the webstore, or 756 // its auto-update URL is from the webstore, treat it as a webstore install. 757 // Note that we ignore some older extensions with blank auto-update URLs 758 // because we are mostly concerned with restrictions on NaCl extensions, 759 // which are newer. 760 if ((extension && extension->from_webstore()) || 761 (extension && extensions::ManifestURL::UpdatesFromGallery(extension)) || 762 (!extension && extension_urls::IsWebstoreUpdateUrl( 763 pending_extension_info->update_url()))) { 764 creation_flags |= Extension::FROM_WEBSTORE; 765 } 766 767 // Bookmark apps being updated is kind of a contradiction, but that's because 768 // we mark the default apps as bookmark apps, and they're hosted in the web 769 // store, thus they can get updated. See http://crbug.com/101605 for more 770 // details. 771 if (extension && extension->from_bookmark()) 772 creation_flags |= Extension::FROM_BOOKMARK; 773 774 if (extension && extension->was_installed_by_default()) 775 creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT; 776 777 installer->set_creation_flags(creation_flags); 778 779 installer->set_delete_source(true); 780 installer->set_download_url(download_url); 781 installer->set_install_cause(extension_misc::INSTALL_CAUSE_UPDATE); 782 installer->InstallCrx(extension_path); 783 784 if (out_crx_installer) 785 *out_crx_installer = installer.get(); 786 787 return true; 788 } 789 790 void ExtensionService::ReloadExtension(const std::string extension_id) { 791 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 792 793 // If the extension is already reloading, don't reload again. 794 if (extension_prefs_->GetDisableReasons(extension_id) & 795 Extension::DISABLE_RELOAD) { 796 return; 797 } 798 799 base::FilePath path; 800 const Extension* current_extension = GetExtensionById(extension_id, false); 801 802 // Disable the extension if it's loaded. It might not be loaded if it crashed. 803 if (current_extension) { 804 // If the extension has an inspector open for its background page, detach 805 // the inspector and hang onto a cookie for it, so that we can reattach 806 // later. 807 // TODO(yoz): this is not incognito-safe! 808 extensions::ProcessManager* manager = system_->process_manager(); 809 extensions::ExtensionHost* host = 810 manager->GetBackgroundHostForExtension(extension_id); 811 if (host && DevToolsAgentHost::HasFor(host->render_view_host())) { 812 // Look for an open inspector for the background page. 813 scoped_refptr<DevToolsAgentHost> agent_host = 814 DevToolsAgentHost::GetOrCreateFor(host->render_view_host()); 815 agent_host->DisconnectRenderViewHost(); 816 orphaned_dev_tools_[extension_id] = agent_host; 817 } 818 819 path = current_extension->path(); 820 // BeingUpgraded is set back to false when the extension is added. 821 SetBeingUpgraded(current_extension, true); 822 DisableExtension(extension_id, Extension::DISABLE_RELOAD); 823 reloading_extensions_.insert(extension_id); 824 } else { 825 path = unloaded_extension_paths_[extension_id]; 826 } 827 828 if (delayed_installs_.Contains(extension_id)) { 829 FinishDelayedInstallation(extension_id); 830 return; 831 } 832 833 // If we're reloading a component extension, use the component extension 834 // loader's reloader. 835 if (component_loader_->Exists(extension_id)) { 836 SetBeingReloaded(extension_id, true); 837 component_loader_->Reload(extension_id); 838 SetBeingReloaded(extension_id, false); 839 return; 840 } 841 842 // Check the installed extensions to see if what we're reloading was already 843 // installed. 844 SetBeingReloaded(extension_id, true); 845 scoped_ptr<ExtensionInfo> installed_extension( 846 extension_prefs_->GetInstalledExtensionInfo(extension_id)); 847 if (installed_extension.get() && 848 installed_extension->extension_manifest.get()) { 849 extensions::InstalledLoader(this).Load(*installed_extension, false); 850 } else { 851 // Otherwise, the extension is unpacked (location LOAD). 852 // We should always be able to remember the extension's path. If it's not in 853 // the map, someone failed to update |unloaded_extension_paths_|. 854 CHECK(!path.empty()); 855 extensions::UnpackedInstaller::Create(this)->Load(path); 856 } 857 // When reloading is done, mark this extension as done reloading. 858 SetBeingReloaded(extension_id, false); 859 } 860 861 bool ExtensionService::UninstallExtension( 862 std::string extension_id, 863 bool external_uninstall, 864 base::string16* error) { 865 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 866 867 scoped_refptr<const Extension> extension(GetInstalledExtension(extension_id)); 868 869 // Callers should not send us nonexistent extensions. 870 CHECK(extension.get()); 871 872 // Policy change which triggers an uninstall will always set 873 // |external_uninstall| to true so this is the only way to uninstall 874 // managed extensions. 875 if (!external_uninstall && 876 !system_->management_policy()->UserMayModifySettings( 877 extension.get(), error)) { 878 content::NotificationService::current()->Notify( 879 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, 880 content::Source<Profile>(profile_), 881 content::Details<const Extension>(extension.get())); 882 return false; 883 } 884 885 syncer::SyncChange sync_change; 886 if (extension_sync_service_) { 887 sync_change = extension_sync_service_->PrepareToSyncUninstallExtension( 888 extension.get(), is_ready()); 889 } 890 891 extensions::ExtensionSystem::Get(profile_)->install_verifier()->Remove( 892 extension->id()); 893 894 if (IsUnacknowledgedExternalExtension(extension.get())) { 895 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", 896 EXTERNAL_EXTENSION_UNINSTALLED, 897 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 898 if (extensions::ManifestURL::UpdatesFromGallery(extension.get())) { 899 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore", 900 EXTERNAL_EXTENSION_UNINSTALLED, 901 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 902 } else { 903 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore", 904 EXTERNAL_EXTENSION_UNINSTALLED, 905 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 906 } 907 } 908 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", 909 extension->GetType(), 100); 910 RecordPermissionMessagesHistogram(extension.get(), 911 "Extensions.Permissions_Uninstall"); 912 913 // Unload before doing more cleanup to ensure that nothing is hanging on to 914 // any of these resources. 915 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); 916 917 // Tell the backend to start deleting installed extensions on the file thread. 918 if (!Manifest::IsUnpackedLocation(extension->location())) { 919 if (!GetFileTaskRunner()->PostTask( 920 FROM_HERE, 921 base::Bind( 922 &extension_file_util::UninstallExtension, 923 install_directory_, 924 extension_id))) 925 NOTREACHED(); 926 } 927 928 GURL launch_web_url_origin( 929 extensions::AppLaunchInfo::GetLaunchWebURL(extension.get()).GetOrigin()); 930 bool is_storage_isolated = 931 extensions::AppIsolationInfo::HasIsolatedStorage(extension.get()); 932 933 if (is_storage_isolated) { 934 BrowserContext::AsyncObliterateStoragePartition( 935 profile_, 936 GetSiteForExtensionId(extension_id), 937 base::Bind(&ExtensionService::OnNeedsToGarbageCollectIsolatedStorage, 938 AsWeakPtr())); 939 } else { 940 if (extension->is_hosted_app() && 941 !profile_->GetExtensionSpecialStoragePolicy()-> 942 IsStorageProtected(launch_web_url_origin)) { 943 extensions::DataDeleter::StartDeleting( 944 profile_, extension_id, launch_web_url_origin); 945 } 946 extensions::DataDeleter::StartDeleting(profile_, extension_id, 947 extension->url()); 948 } 949 950 UntrackTerminatedExtension(extension_id); 951 952 // Notify interested parties that we've uninstalled this extension. 953 content::NotificationService::current()->Notify( 954 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 955 content::Source<Profile>(profile_), 956 content::Details<const Extension>(extension.get())); 957 958 if (extension_sync_service_) { 959 extension_sync_service_->ProcessSyncUninstallExtension(extension_id, 960 sync_change); 961 } 962 963 delayed_installs_.Remove(extension_id); 964 965 PruneSharedModulesOnUninstall(extension.get()); 966 967 extension_prefs_->OnExtensionUninstalled(extension_id, extension->location(), 968 external_uninstall); 969 970 // Track the uninstallation. 971 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); 972 973 return true; 974 } 975 976 bool ExtensionService::IsExtensionEnabled( 977 const std::string& extension_id) const { 978 if (extensions_.Contains(extension_id) || 979 terminated_extensions_.Contains(extension_id)) { 980 return true; 981 } 982 983 if (disabled_extensions_.Contains(extension_id) || 984 blacklisted_extensions_.Contains(extension_id)) { 985 return false; 986 } 987 988 // If the extension hasn't been loaded yet, check the prefs for it. Assume 989 // enabled unless otherwise noted. 990 return !extension_prefs_->IsExtensionDisabled(extension_id) && 991 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); 992 } 993 994 bool ExtensionService::IsExternalExtensionUninstalled( 995 const std::string& extension_id) const { 996 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); 997 } 998 999 void ExtensionService::EnableExtension(const std::string& extension_id) { 1000 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1001 1002 if (IsExtensionEnabled(extension_id)) 1003 return; 1004 const Extension* extension = disabled_extensions_.GetByID(extension_id); 1005 1006 ManagementPolicy* policy = system_->management_policy(); 1007 if (extension && policy->MustRemainDisabled(extension, NULL, NULL)) { 1008 UMA_HISTOGRAM_COUNTS_100("Extensions.EnableDeniedByPolicy", 1); 1009 return; 1010 } 1011 1012 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); 1013 extension_prefs_->ClearDisableReasons(extension_id); 1014 1015 // This can happen if sync enables an extension that is not 1016 // installed yet. 1017 if (!extension) 1018 return; 1019 1020 if (IsUnacknowledgedExternalExtension(extension)) { 1021 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", 1022 EXTERNAL_EXTENSION_REENABLED, 1023 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 1024 if (extensions::ManifestURL::UpdatesFromGallery(extension)) { 1025 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore", 1026 EXTERNAL_EXTENSION_REENABLED, 1027 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 1028 } else { 1029 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore", 1030 EXTERNAL_EXTENSION_REENABLED, 1031 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 1032 } 1033 AcknowledgeExternalExtension(extension->id()); 1034 } 1035 1036 // Move it over to the enabled list. 1037 extensions_.Insert(make_scoped_refptr(extension)); 1038 disabled_extensions_.Remove(extension->id()); 1039 1040 NotifyExtensionLoaded(extension); 1041 1042 // Notify listeners that the extension was enabled. 1043 content::NotificationService::current()->Notify( 1044 chrome::NOTIFICATION_EXTENSION_ENABLED, 1045 content::Source<Profile>(profile_), 1046 content::Details<const Extension>(extension)); 1047 1048 if (extension_sync_service_) 1049 extension_sync_service_->SyncEnableExtension(*extension); 1050 } 1051 1052 void ExtensionService::DisableExtension( 1053 const std::string& extension_id, 1054 Extension::DisableReason disable_reason) { 1055 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1056 1057 // The extension may have been disabled already. 1058 if (!IsExtensionEnabled(extension_id)) 1059 return; 1060 1061 const Extension* extension = GetInstalledExtension(extension_id); 1062 // |extension| can be NULL if sync disables an extension that is not 1063 // installed yet. 1064 if (extension && 1065 disable_reason != Extension::DISABLE_RELOAD && 1066 !system_->management_policy()->UserMayModifySettings(extension, NULL)) { 1067 return; 1068 } 1069 1070 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); 1071 extension_prefs_->AddDisableReason(extension_id, disable_reason); 1072 1073 int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_DISABLED; 1074 extension = GetExtensionById(extension_id, include_mask); 1075 if (!extension) 1076 return; 1077 1078 // Reset the background_page_ready flag 1079 if (extensions::BackgroundInfo::HasBackgroundPage(extension)) 1080 extension_runtime_data_[extension->id()].background_page_ready = false; 1081 1082 // Move it over to the disabled list. Don't send a second unload notification 1083 // for terminated extensions being disabled. 1084 disabled_extensions_.Insert(make_scoped_refptr(extension)); 1085 if (extensions_.Contains(extension->id())) { 1086 extensions_.Remove(extension->id()); 1087 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::REASON_DISABLE); 1088 } else { 1089 terminated_extensions_.Remove(extension->id()); 1090 } 1091 1092 if (extension_sync_service_) 1093 extension_sync_service_->SyncDisableExtension(*extension); 1094 } 1095 1096 void ExtensionService::DisableUserExtensions( 1097 const std::vector<std::string>& except_ids) { 1098 extensions::ManagementPolicy* management_policy = 1099 system_->management_policy(); 1100 extensions::ExtensionList to_disable; 1101 1102 for (ExtensionSet::const_iterator extension = extensions_.begin(); 1103 extension != extensions_.end(); ++extension) { 1104 if (management_policy->UserMayModifySettings(extension->get(), NULL)) 1105 to_disable.push_back(*extension); 1106 } 1107 for (ExtensionSet::const_iterator extension = terminated_extensions_.begin(); 1108 extension != terminated_extensions_.end(); ++extension) { 1109 if (management_policy->UserMayModifySettings(extension->get(), NULL)) 1110 to_disable.push_back(*extension); 1111 } 1112 1113 for (extensions::ExtensionList::const_iterator extension = to_disable.begin(); 1114 extension != to_disable.end(); ++extension) { 1115 if ((*extension)->was_installed_by_default() && 1116 extension_urls::IsWebstoreUpdateUrl( 1117 extensions::ManifestURL::GetUpdateURL(*extension))) 1118 continue; 1119 const std::string& id = (*extension)->id(); 1120 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) 1121 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); 1122 } 1123 } 1124 1125 void ExtensionService::GrantPermissionsAndEnableExtension( 1126 const Extension* extension) { 1127 GrantPermissions(extension); 1128 RecordPermissionMessagesHistogram( 1129 extension, "Extensions.Permissions_ReEnable"); 1130 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); 1131 EnableExtension(extension->id()); 1132 } 1133 1134 void ExtensionService::GrantPermissions(const Extension* extension) { 1135 CHECK(extension); 1136 extensions::PermissionsUpdater perms_updater(profile()); 1137 perms_updater.GrantActivePermissions(extension); 1138 } 1139 1140 // static 1141 void ExtensionService::RecordPermissionMessagesHistogram( 1142 const Extension* extension, const char* histogram) { 1143 // Since this is called from multiple sources, and since the histogram macros 1144 // use statics, we need to manually lookup the histogram ourselves. 1145 base::HistogramBase* counter = base::LinearHistogram::FactoryGet( 1146 histogram, 1147 1, 1148 PermissionMessage::kEnumBoundary, 1149 PermissionMessage::kEnumBoundary + 1, 1150 base::HistogramBase::kUmaTargetedHistogramFlag); 1151 1152 PermissionMessages permissions = 1153 extensions::PermissionsData::GetPermissionMessages(extension); 1154 if (permissions.empty()) { 1155 counter->Add(PermissionMessage::kNone); 1156 } else { 1157 for (PermissionMessages::iterator it = permissions.begin(); 1158 it != permissions.end(); ++it) 1159 counter->Add(it->id()); 1160 } 1161 } 1162 1163 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) { 1164 // The ChromeURLRequestContexts need to be first to know that the extension 1165 // was loaded, otherwise a race can arise where a renderer that is created 1166 // for the extension may try to load an extension URL with an extension id 1167 // that the request context doesn't yet know about. The profile is responsible 1168 // for ensuring its URLRequestContexts appropriately discover the loaded 1169 // extension. 1170 system_->RegisterExtensionWithRequestContexts(extension); 1171 1172 // Tell renderers about the new extension, unless it's a theme (renderers 1173 // don't need to know about themes). 1174 if (!extension->is_theme()) { 1175 for (content::RenderProcessHost::iterator i( 1176 content::RenderProcessHost::AllHostsIterator()); 1177 !i.IsAtEnd(); i.Advance()) { 1178 content::RenderProcessHost* host = i.GetCurrentValue(); 1179 Profile* host_profile = 1180 Profile::FromBrowserContext(host->GetBrowserContext()); 1181 if (host_profile->GetOriginalProfile() == 1182 profile_->GetOriginalProfile()) { 1183 std::vector<ExtensionMsg_Loaded_Params> loaded_extensions( 1184 1, ExtensionMsg_Loaded_Params(extension)); 1185 host->Send( 1186 new ExtensionMsg_Loaded(loaded_extensions)); 1187 } 1188 } 1189 } 1190 1191 // Tell subsystems that use the EXTENSION_LOADED notification about the new 1192 // extension. 1193 // 1194 // NOTE: It is important that this happen after notifying the renderers about 1195 // the new extensions so that if we navigate to an extension URL in 1196 // NOTIFICATION_EXTENSION_LOADED, the renderer is guaranteed to know about it. 1197 content::NotificationService::current()->Notify( 1198 chrome::NOTIFICATION_EXTENSION_LOADED, 1199 content::Source<Profile>(profile_), 1200 content::Details<const Extension>(extension)); 1201 1202 // Tell a random-ass collection of other subsystems about the new extension. 1203 // TODO(aa): What should we do with all this goop? Can it move into the 1204 // relevant objects via EXTENSION_LOADED? 1205 1206 profile_->GetExtensionSpecialStoragePolicy()-> 1207 GrantRightsForExtension(extension); 1208 1209 UpdateActiveExtensionsInCrashReporter(); 1210 1211 // If the extension has permission to load chrome://favicon/ resources we need 1212 // to make sure that the FaviconSource is registered with the 1213 // ChromeURLDataManager. 1214 if (extensions::PermissionsData::HasHostPermission( 1215 extension, GURL(chrome::kChromeUIFaviconURL))) { 1216 FaviconSource* favicon_source = new FaviconSource(profile_, 1217 FaviconSource::FAVICON); 1218 content::URLDataSource::Add(profile_, favicon_source); 1219 } 1220 1221 #if !defined(OS_ANDROID) 1222 // Same for chrome://theme/ resources. 1223 if (extensions::PermissionsData::HasHostPermission( 1224 extension, GURL(chrome::kChromeUIThemeURL))) { 1225 ThemeSource* theme_source = new ThemeSource(profile_); 1226 content::URLDataSource::Add(profile_, theme_source); 1227 } 1228 #endif 1229 1230 // Same for chrome://thumb/ resources. 1231 if (extensions::PermissionsData::HasHostPermission( 1232 extension, GURL(chrome::kChromeUIThumbnailURL))) { 1233 ThumbnailSource* thumbnail_source = new ThumbnailSource(profile_, false); 1234 content::URLDataSource::Add(profile_, thumbnail_source); 1235 } 1236 } 1237 1238 void ExtensionService::NotifyExtensionUnloaded( 1239 const Extension* extension, 1240 UnloadedExtensionInfo::Reason reason) { 1241 UnloadedExtensionInfo details(extension, reason); 1242 content::NotificationService::current()->Notify( 1243 chrome::NOTIFICATION_EXTENSION_UNLOADED, 1244 content::Source<Profile>(profile_), 1245 content::Details<UnloadedExtensionInfo>(&details)); 1246 1247 for (content::RenderProcessHost::iterator i( 1248 content::RenderProcessHost::AllHostsIterator()); 1249 !i.IsAtEnd(); i.Advance()) { 1250 content::RenderProcessHost* host = i.GetCurrentValue(); 1251 Profile* host_profile = 1252 Profile::FromBrowserContext(host->GetBrowserContext()); 1253 if (host_profile->GetOriginalProfile() == profile_->GetOriginalProfile()) 1254 host->Send(new ExtensionMsg_Unloaded(extension->id())); 1255 } 1256 1257 system_->UnregisterExtensionWithRequestContexts(extension->id(), reason); 1258 profile_->GetExtensionSpecialStoragePolicy()-> 1259 RevokeRightsForExtension(extension); 1260 1261 #if defined(OS_CHROMEOS) 1262 // Revoke external file access for the extension from its file system context. 1263 // It is safe to access the extension's storage partition at this point. The 1264 // storage partition may get destroyed only after the extension gets unloaded. 1265 GURL site = extensions::ExtensionSystem::Get(profile_)->extension_service()-> 1266 GetSiteForExtensionId(extension->id()); 1267 fileapi::FileSystemContext* filesystem_context = 1268 BrowserContext::GetStoragePartitionForSite(profile_, site)-> 1269 GetFileSystemContext(); 1270 if (filesystem_context && filesystem_context->external_backend()) { 1271 filesystem_context->external_backend()-> 1272 RevokeAccessForExtension(extension->id()); 1273 } 1274 #endif 1275 1276 UpdateActiveExtensionsInCrashReporter(); 1277 } 1278 1279 Profile* ExtensionService::profile() { 1280 return profile_; 1281 } 1282 1283 extensions::ExtensionPrefs* ExtensionService::extension_prefs() { 1284 return extension_prefs_; 1285 } 1286 1287 const extensions::ExtensionPrefs* ExtensionService::extension_prefs() const { 1288 return extension_prefs_; 1289 } 1290 1291 extensions::SettingsFrontend* ExtensionService::settings_frontend() { 1292 return settings_frontend_.get(); 1293 } 1294 1295 extensions::ContentSettingsStore* ExtensionService::GetContentSettingsStore() { 1296 return extension_prefs()->content_settings_store(); 1297 } 1298 1299 bool ExtensionService::is_ready() { 1300 return ready_->is_signaled(); 1301 } 1302 1303 base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() { 1304 if (file_task_runner_.get()) 1305 return file_task_runner_.get(); 1306 1307 // We should be able to interrupt any part of extension install process during 1308 // shutdown. SKIP_ON_SHUTDOWN ensures that not started extension install tasks 1309 // will be ignored/deleted while we will block on started tasks. 1310 std::string token("ext_install-"); 1311 token.append(profile_->GetPath().AsUTF8Unsafe()); 1312 file_task_runner_ = BrowserThread::GetBlockingPool()-> 1313 GetSequencedTaskRunnerWithShutdownBehavior( 1314 BrowserThread::GetBlockingPool()->GetNamedSequenceToken(token), 1315 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 1316 return file_task_runner_.get(); 1317 } 1318 1319 extensions::ExtensionUpdater* ExtensionService::updater() { 1320 return updater_.get(); 1321 } 1322 1323 void ExtensionService::CheckManagementPolicy() { 1324 std::vector<std::string> to_unload; 1325 std::map<std::string, Extension::DisableReason> to_disable; 1326 1327 // Loop through the extensions list, finding extensions we need to unload or 1328 // disable. 1329 for (ExtensionSet::const_iterator iter = extensions_.begin(); 1330 iter != extensions_.end(); ++iter) { 1331 const Extension* extension = (iter->get()); 1332 if (!system_->management_policy()->UserMayLoad(extension, NULL)) 1333 to_unload.push_back(extension->id()); 1334 Extension::DisableReason disable_reason = Extension::DISABLE_NONE; 1335 if (system_->management_policy()->MustRemainDisabled( 1336 extension, &disable_reason, NULL)) 1337 to_disable[extension->id()] = disable_reason; 1338 } 1339 1340 for (size_t i = 0; i < to_unload.size(); ++i) 1341 UnloadExtension(to_unload[i], UnloadedExtensionInfo::REASON_DISABLE); 1342 1343 for (std::map<std::string, Extension::DisableReason>::const_iterator i = 1344 to_disable.begin(); i != to_disable.end(); ++i) 1345 DisableExtension(i->first, i->second); 1346 } 1347 1348 void ExtensionService::CheckForUpdatesSoon() { 1349 if (updater()) { 1350 if (AreAllExternalProvidersReady()) { 1351 updater()->CheckSoon(); 1352 } else { 1353 // Sync can start updating before all the external providers are ready 1354 // during startup. Start the update as soon as those providers are ready, 1355 // but not before. 1356 update_once_all_providers_are_ready_ = true; 1357 } 1358 } else { 1359 LOG(WARNING) << "CheckForUpdatesSoon() called with auto-update turned off"; 1360 } 1361 } 1362 1363 void ExtensionService::OnExtensionMoved( 1364 const std::string& moved_extension_id, 1365 const std::string& predecessor_extension_id, 1366 const std::string& successor_extension_id) { 1367 extension_prefs_->app_sorting()->OnExtensionMoved( 1368 moved_extension_id, 1369 predecessor_extension_id, 1370 successor_extension_id); 1371 1372 const Extension* extension = GetInstalledExtension(moved_extension_id); 1373 if (extension_sync_service_ && extension) { 1374 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1375 } 1376 } 1377 1378 // Some extensions will autoupdate themselves externally from Chrome. These 1379 // are typically part of some larger client application package. To support 1380 // these, the extension will register its location in the the preferences file 1381 // (and also, on Windows, in the registry) and this code will periodically 1382 // check that location for a .crx file, which it will then install locally if 1383 // a new version is available. 1384 // Errors are reported through ExtensionErrorReporter. Succcess is not 1385 // reported. 1386 void ExtensionService::CheckForExternalUpdates() { 1387 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1388 1389 // Note that this installation is intentionally silent (since it didn't 1390 // go through the front-end). Extensions that are registered in this 1391 // way are effectively considered 'pre-bundled', and so implicitly 1392 // trusted. In general, if something has HKLM or filesystem access, 1393 // they could install an extension manually themselves anyway. 1394 1395 // Ask each external extension provider to give us a call back for each 1396 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. 1397 extensions::ProviderCollection::const_iterator i; 1398 for (i = external_extension_providers_.begin(); 1399 i != external_extension_providers_.end(); ++i) { 1400 extensions::ExternalProviderInterface* provider = i->get(); 1401 provider->VisitRegisteredExtension(); 1402 } 1403 1404 // Do any required work that we would have done after completion of all 1405 // providers. 1406 if (external_extension_providers_.empty()) { 1407 OnAllExternalProvidersReady(); 1408 } 1409 } 1410 1411 void ExtensionService::OnExternalProviderReady( 1412 const extensions::ExternalProviderInterface* provider) { 1413 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1414 CHECK(provider->IsReady()); 1415 1416 // An external provider has finished loading. We only take action 1417 // if all of them are finished. So we check them first. 1418 if (AreAllExternalProvidersReady()) 1419 OnAllExternalProvidersReady(); 1420 } 1421 1422 bool ExtensionService::AreAllExternalProvidersReady() const { 1423 extensions::ProviderCollection::const_iterator i; 1424 for (i = external_extension_providers_.begin(); 1425 i != external_extension_providers_.end(); ++i) { 1426 if (!i->get()->IsReady()) 1427 return false; 1428 } 1429 return true; 1430 } 1431 1432 void ExtensionService::OnAllExternalProvidersReady() { 1433 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1434 base::TimeDelta elapsed = base::Time::Now() - profile_->GetStartTime(); 1435 UMA_HISTOGRAM_TIMES("Extension.ExternalProvidersReadyAfter", elapsed); 1436 1437 // Install any pending extensions. 1438 if (update_once_all_providers_are_ready_ && updater()) { 1439 update_once_all_providers_are_ready_ = false; 1440 extensions::ExtensionUpdater::CheckParams params; 1441 params.callback = external_updates_finished_callback_; 1442 updater()->CheckNow(params); 1443 } 1444 1445 // Uninstall all the unclaimed extensions. 1446 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> extensions_info( 1447 extension_prefs_->GetInstalledExtensionsInfo()); 1448 for (size_t i = 0; i < extensions_info->size(); ++i) { 1449 ExtensionInfo* info = extensions_info->at(i).get(); 1450 if (Manifest::IsExternalLocation(info->extension_location)) 1451 CheckExternalUninstall(info->extension_id); 1452 } 1453 IdentifyAlertableExtensions(); 1454 } 1455 1456 void ExtensionService::IdentifyAlertableExtensions() { 1457 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1458 1459 // Build up the lists of extensions that require acknowledgment. If this is 1460 // the first time, grandfather extensions that would have caused 1461 // notification. 1462 extension_error_ui_.reset(ExtensionErrorUI::Create(this)); 1463 1464 bool did_show_alert = false; 1465 if (PopulateExtensionErrorUI(extension_error_ui_.get())) { 1466 if (!is_first_run_) { 1467 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1468 did_show_alert = extension_error_ui_->ShowErrorInBubbleView(); 1469 } else { 1470 // First run. Just acknowledge all the extensions, silently, by 1471 // shortcutting the display of the UI and going straight to the 1472 // callback for pressing the Accept button. 1473 HandleExtensionAlertAccept(); 1474 } 1475 } 1476 1477 UpdateExternalExtensionAlert(); 1478 1479 if (!did_show_alert) 1480 extension_error_ui_.reset(); 1481 } 1482 1483 bool ExtensionService::PopulateExtensionErrorUI( 1484 ExtensionErrorUI* extension_error_ui) { 1485 bool needs_alert = false; 1486 1487 // Extensions that are blacklisted. 1488 for (ExtensionSet::const_iterator it = blacklisted_extensions_.begin(); 1489 it != blacklisted_extensions_.end(); ++it) { 1490 std::string id = (*it)->id(); 1491 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(id)) { 1492 extension_error_ui->AddBlacklistedExtension(id); 1493 needs_alert = true; 1494 } 1495 } 1496 1497 for (ExtensionSet::const_iterator iter = extensions_.begin(); 1498 iter != extensions_.end(); ++iter) { 1499 const Extension* e = iter->get(); 1500 1501 // Skip for extensions that have pending updates. They will be checked again 1502 // once the pending update is finished. 1503 if (pending_extension_manager()->IsIdPending(e->id())) 1504 continue; 1505 1506 // Extensions disabled by policy. Note: this no longer includes blacklisted 1507 // extensions, though we still show the same UI. 1508 if (!system_->management_policy()->UserMayLoad(e, NULL)) { 1509 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { 1510 extension_error_ui->AddBlacklistedExtension(e->id()); 1511 needs_alert = true; 1512 } 1513 } 1514 } 1515 1516 return needs_alert; 1517 } 1518 1519 void ExtensionService::HandleExtensionAlertClosed() { 1520 const ExtensionIdSet* extension_ids = 1521 extension_error_ui_->get_blacklisted_extension_ids(); 1522 for (ExtensionIdSet::const_iterator iter = extension_ids->begin(); 1523 iter != extension_ids->end(); ++iter) { 1524 extension_prefs_->AcknowledgeBlacklistedExtension(*iter); 1525 } 1526 extension_error_ui_.reset(); 1527 } 1528 1529 void ExtensionService::HandleExtensionAlertAccept() { 1530 extension_error_ui_->Close(); 1531 } 1532 1533 void ExtensionService::AcknowledgeExternalExtension(const std::string& id) { 1534 extension_prefs_->AcknowledgeExternalExtension(id); 1535 UpdateExternalExtensionAlert(); 1536 } 1537 1538 bool ExtensionService::IsUnacknowledgedExternalExtension( 1539 const Extension* extension) { 1540 if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) 1541 return false; 1542 1543 return (Manifest::IsExternalLocation(extension->location()) && 1544 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id()) && 1545 !(extension_prefs_->GetDisableReasons(extension->id()) & 1546 Extension::DISABLE_SIDELOAD_WIPEOUT)); 1547 } 1548 1549 void ExtensionService::ReconcileKnownDisabled() { 1550 ExtensionIdSet known_disabled_ids; 1551 if (!extension_prefs_->GetKnownDisabled(&known_disabled_ids)) { 1552 extension_prefs_->SetKnownDisabled(disabled_extensions_.GetIDs()); 1553 UMA_HISTOGRAM_BOOLEAN("Extensions.KnownDisabledInitialized", true); 1554 return; 1555 } 1556 1557 // Both |known_disabled_ids| and |extensions_| are ordered (by definition 1558 // of std::map and std::set). Iterate forward over both sets in parallel 1559 // to find matching IDs and disable the corresponding extensions. 1560 ExtensionSet::const_iterator extensions_it = extensions_.begin(); 1561 ExtensionIdSet::const_iterator known_disabled_ids_it = 1562 known_disabled_ids.begin(); 1563 int known_disabled_count = 0; 1564 while (extensions_it != extensions_.end() && 1565 known_disabled_ids_it != known_disabled_ids.end()) { 1566 const std::string& extension_id = extensions_it->get()->id(); 1567 const int comparison = extension_id.compare(*known_disabled_ids_it); 1568 if (comparison < 0) { 1569 ++extensions_it; 1570 } else if (comparison > 0) { 1571 ++known_disabled_ids_it; 1572 } else { 1573 ++known_disabled_count; 1574 // Advance |extensions_it| immediately as it will be invalidated upon 1575 // disabling the extension it points to. 1576 ++extensions_it; 1577 ++known_disabled_ids_it; 1578 DisableExtension(extension_id, Extension::DISABLE_KNOWN_DISABLED); 1579 } 1580 } 1581 UMA_HISTOGRAM_COUNTS_100("Extensions.KnownDisabledReDisabled", 1582 known_disabled_count); 1583 1584 // Update the list of known disabled to reflect every change to 1585 // |disabled_extensions_| from this point forward. 1586 disabled_extensions_.set_modification_callback( 1587 base::Bind(&extensions::ExtensionPrefs::SetKnownDisabled, 1588 base::Unretained(extension_prefs_))); 1589 } 1590 1591 void ExtensionService::HandleExtensionAlertDetails() { 1592 extension_error_ui_->ShowExtensions(); 1593 // ShowExtensions may cause the error UI to close synchronously, e.g. if it 1594 // causes a navigation. 1595 if (extension_error_ui_) 1596 extension_error_ui_->Close(); 1597 } 1598 1599 void ExtensionService::UpdateExternalExtensionAlert() { 1600 if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) 1601 return; 1602 1603 const Extension* extension = NULL; 1604 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); 1605 iter != disabled_extensions_.end(); ++iter) { 1606 const Extension* e = iter->get(); 1607 if (IsUnacknowledgedExternalExtension(e)) { 1608 extension = e; 1609 break; 1610 } 1611 } 1612 1613 if (extension) { 1614 if (!extensions::HasExternalInstallError(this)) { 1615 if (extension_prefs_->IncrementAcknowledgePromptCount(extension->id()) > 1616 kMaxExtensionAcknowledgePromptCount) { 1617 // Stop prompting for this extension, and check if there's another 1618 // one that needs prompting. 1619 extension_prefs_->AcknowledgeExternalExtension(extension->id()); 1620 UpdateExternalExtensionAlert(); 1621 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", 1622 EXTERNAL_EXTENSION_IGNORED, 1623 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 1624 if (extensions::ManifestURL::UpdatesFromGallery(extension)) { 1625 UMA_HISTOGRAM_ENUMERATION( 1626 "Extensions.ExternalExtensionEventWebstore", 1627 EXTERNAL_EXTENSION_IGNORED, 1628 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 1629 } else { 1630 UMA_HISTOGRAM_ENUMERATION( 1631 "Extensions.ExternalExtensionEventNonWebstore", 1632 EXTERNAL_EXTENSION_IGNORED, 1633 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 1634 } 1635 return; 1636 } 1637 if (is_first_run_) 1638 extension_prefs_->SetExternalInstallFirstRun(extension->id()); 1639 // first_run is true if the extension was installed during a first run 1640 // (even if it's post-first run now). 1641 bool first_run = extension_prefs_->IsExternalInstallFirstRun( 1642 extension->id()); 1643 extensions::AddExternalInstallError(this, extension, first_run); 1644 } 1645 } else { 1646 extensions::RemoveExternalInstallError(this); 1647 } 1648 } 1649 1650 void ExtensionService::UnloadExtension( 1651 const std::string& extension_id, 1652 UnloadedExtensionInfo::Reason reason) { 1653 // Make sure the extension gets deleted after we return from this function. 1654 int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_TERMINATED; 1655 scoped_refptr<const Extension> extension( 1656 GetExtensionById(extension_id, include_mask)); 1657 1658 // This method can be called via PostTask, so the extension may have been 1659 // unloaded by the time this runs. 1660 if (!extension.get()) { 1661 // In case the extension may have crashed/uninstalled. Allow the profile to 1662 // clean up its RequestContexts. 1663 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); 1664 return; 1665 } 1666 1667 // Keep information about the extension so that we can reload it later 1668 // even if it's not permanently installed. 1669 unloaded_extension_paths_[extension->id()] = extension->path(); 1670 1671 // Clean up if the extension is meant to be enabled after a reload. 1672 reloading_extensions_.erase(extension->id()); 1673 1674 // Clean up runtime data. 1675 extension_runtime_data_.erase(extension_id); 1676 1677 if (disabled_extensions_.Contains(extension->id())) { 1678 disabled_extensions_.Remove(extension->id()); 1679 // Make sure the profile cleans up its RequestContexts when an already 1680 // disabled extension is unloaded (since they are also tracking the disabled 1681 // extensions). 1682 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); 1683 } else { 1684 // Remove the extension from our list. 1685 extensions_.Remove(extension->id()); 1686 NotifyExtensionUnloaded(extension.get(), reason); 1687 } 1688 1689 content::NotificationService::current()->Notify( 1690 chrome::NOTIFICATION_EXTENSION_REMOVED, 1691 content::Source<Profile>(profile_), 1692 content::Details<const Extension>(extension.get())); 1693 } 1694 1695 void ExtensionService::RemoveComponentExtension( 1696 const std::string& extension_id) { 1697 scoped_refptr<const Extension> extension( 1698 GetExtensionById(extension_id, false)); 1699 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); 1700 content::NotificationService::current()->Notify( 1701 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 1702 content::Source<Profile>(profile_), 1703 content::Details<const Extension>(extension.get())); 1704 } 1705 1706 void ExtensionService::UnloadAllExtensions() { 1707 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); 1708 1709 extensions_.Clear(); 1710 disabled_extensions_.Clear(); 1711 terminated_extensions_.Clear(); 1712 extension_runtime_data_.clear(); 1713 1714 // TODO(erikkay) should there be a notification for this? We can't use 1715 // EXTENSION_UNLOADED since that implies that the extension has been disabled 1716 // or uninstalled, and UnloadAll is just part of shutdown. 1717 } 1718 1719 void ExtensionService::ReloadExtensions() { 1720 UnloadAllExtensions(); 1721 component_loader_->LoadAll(); 1722 extensions::InstalledLoader(this).LoadAllExtensions(); 1723 // Don't call SetReadyAndNotifyListeners() since tests call this multiple 1724 // times. 1725 } 1726 1727 void ExtensionService::GarbageCollectExtensions() { 1728 #if defined(OS_CHROMEOS) 1729 if (disable_garbage_collection_) 1730 return; 1731 #endif 1732 1733 if (extension_prefs_->pref_service()->ReadOnly()) 1734 return; 1735 1736 if (pending_extension_manager()->HasPendingExtensions()) { 1737 // Don't garbage collect while there are pending installations, which may 1738 // be using the temporary installation directory. Try to garbage collect 1739 // again later. 1740 base::MessageLoop::current()->PostDelayedTask( 1741 FROM_HERE, 1742 base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()), 1743 base::TimeDelta::FromSeconds(kGarbageCollectRetryDelay)); 1744 return; 1745 } 1746 1747 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> info( 1748 extension_prefs_->GetInstalledExtensionsInfo()); 1749 1750 std::multimap<std::string, base::FilePath> extension_paths; 1751 for (size_t i = 0; i < info->size(); ++i) 1752 extension_paths.insert(std::make_pair(info->at(i)->extension_id, 1753 info->at(i)->extension_path)); 1754 1755 info = extension_prefs_->GetAllDelayedInstallInfo(); 1756 for (size_t i = 0; i < info->size(); ++i) 1757 extension_paths.insert(std::make_pair(info->at(i)->extension_id, 1758 info->at(i)->extension_path)); 1759 1760 if (!GetFileTaskRunner()->PostTask( 1761 FROM_HERE, 1762 base::Bind( 1763 &extension_file_util::GarbageCollectExtensions, 1764 install_directory_, 1765 extension_paths))) { 1766 NOTREACHED(); 1767 } 1768 } 1769 1770 void ExtensionService::SetReadyAndNotifyListeners() { 1771 ready_->Signal(); 1772 content::NotificationService::current()->Notify( 1773 chrome::NOTIFICATION_EXTENSIONS_READY, 1774 content::Source<Profile>(profile_), 1775 content::NotificationService::NoDetails()); 1776 } 1777 1778 void ExtensionService::OnLoadedInstalledExtensions() { 1779 if (updater_) 1780 updater_->Start(); 1781 1782 OnBlacklistUpdated(); 1783 } 1784 1785 void ExtensionService::AddExtension(const Extension* extension) { 1786 // TODO(jstritar): We may be able to get rid of this branch by overriding the 1787 // default extension state to DISABLED when the --disable-extensions flag 1788 // is set (http://crbug.com/29067). 1789 if (!extensions_enabled() && 1790 !extension->is_theme() && 1791 extension->location() != Manifest::COMPONENT && 1792 !Manifest::IsExternalLocation(extension->location())) { 1793 return; 1794 } 1795 1796 bool is_extension_upgrade = false; 1797 bool is_extension_installed = false; 1798 const Extension* old = GetInstalledExtension(extension->id()); 1799 if (old) { 1800 is_extension_installed = true; 1801 int version_compare_result = 1802 extension->version()->CompareTo(*(old->version())); 1803 is_extension_upgrade = version_compare_result > 0; 1804 // Other than for unpacked extensions, CrxInstaller should have guaranteed 1805 // that we aren't downgrading. 1806 if (!Manifest::IsUnpackedLocation(extension->location())) 1807 CHECK_GE(version_compare_result, 0); 1808 } 1809 SetBeingUpgraded(extension, is_extension_upgrade); 1810 1811 // The extension is now loaded, remove its data from unloaded extension map. 1812 unloaded_extension_paths_.erase(extension->id()); 1813 1814 // If a terminated extension is loaded, remove it from the terminated list. 1815 UntrackTerminatedExtension(extension->id()); 1816 1817 // If the extension was disabled for a reload, then enable it. 1818 bool reloading = reloading_extensions_.erase(extension->id()) > 0; 1819 1820 // Check if the extension's privileges have changed and mark the 1821 // extension disabled if necessary. 1822 CheckPermissionsIncrease(extension, is_extension_installed); 1823 1824 if (is_extension_installed && !reloading) { 1825 // To upgrade an extension in place, unload the old one and then load the 1826 // new one. ReloadExtension disables the extension, which is sufficient. 1827 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); 1828 } 1829 1830 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { 1831 // Only prefs is checked for the blacklist. We rely on callers to check the 1832 // blacklist before calling into here, e.g. CrxInstaller checks before 1833 // installation then threads through the install and pending install flow 1834 // of this class, and we check when loading installed extensions. 1835 blacklisted_extensions_.Insert(extension); 1836 } else if (!reloading && 1837 extension_prefs_->IsExtensionDisabled(extension->id())) { 1838 disabled_extensions_.Insert(extension); 1839 if (extension_sync_service_) 1840 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1841 content::NotificationService::current()->Notify( 1842 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, 1843 content::Source<Profile>(profile_), 1844 content::Details<const Extension>(extension)); 1845 1846 // Show the extension disabled error if a permissions increase was the 1847 // only reason it was disabled. 1848 if (extension_prefs_->GetDisableReasons(extension->id()) == 1849 Extension::DISABLE_PERMISSIONS_INCREASE) { 1850 extensions::AddExtensionDisabledError(this, extension); 1851 } 1852 } else if (reloading) { 1853 // Replace the old extension with the new version. 1854 CHECK(!disabled_extensions_.Insert(extension)); 1855 EnableExtension(extension->id()); 1856 } else { 1857 // All apps that are displayed in the launcher are ordered by their ordinals 1858 // so we must ensure they have valid ordinals. 1859 if (extension->RequiresSortOrdinal()) { 1860 if (!extension->ShouldDisplayInNewTabPage()) { 1861 extension_prefs_->app_sorting()->MarkExtensionAsHidden(extension->id()); 1862 } 1863 extension_prefs_->app_sorting()->EnsureValidOrdinals( 1864 extension->id(), syncer::StringOrdinal()); 1865 } 1866 1867 extensions_.Insert(extension); 1868 if (extension_sync_service_) 1869 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1870 NotifyExtensionLoaded(extension); 1871 } 1872 SetBeingUpgraded(extension, false); 1873 } 1874 1875 void ExtensionService::AddComponentExtension(const Extension* extension) { 1876 const std::string old_version_string( 1877 extension_prefs_->GetVersionString(extension->id())); 1878 const Version old_version(old_version_string); 1879 1880 VLOG(1) << "AddComponentExtension " << extension->name(); 1881 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { 1882 VLOG(1) << "Component extension " << extension->name() << " (" 1883 << extension->id() << ") installing/upgrading from '" 1884 << old_version_string << "' to " << extension->version()->GetString(); 1885 1886 AddNewOrUpdatedExtension(extension, 1887 Extension::ENABLED_COMPONENT, 1888 extensions::Blacklist::NOT_BLACKLISTED, 1889 syncer::StringOrdinal()); 1890 return; 1891 } 1892 1893 AddExtension(extension); 1894 } 1895 1896 void ExtensionService::UpdateActivePermissions(const Extension* extension) { 1897 // If the extension has used the optional permissions API, it will have a 1898 // custom set of active permissions defined in the extension prefs. Here, 1899 // we update the extension's active permissions based on the prefs. 1900 scoped_refptr<PermissionSet> active_permissions = 1901 extension_prefs()->GetActivePermissions(extension->id()); 1902 1903 if (active_permissions.get()) { 1904 // We restrict the active permissions to be within the bounds defined in the 1905 // extension's manifest. 1906 // a) active permissions must be a subset of optional + default permissions 1907 // b) active permissions must contains all default permissions 1908 scoped_refptr<PermissionSet> total_permissions = 1909 PermissionSet::CreateUnion( 1910 extensions::PermissionsData::GetRequiredPermissions(extension), 1911 extensions::PermissionsData::GetOptionalPermissions(extension)); 1912 1913 // Make sure the active permissions contain no more than optional + default. 1914 scoped_refptr<PermissionSet> adjusted_active = 1915 PermissionSet::CreateIntersection( 1916 total_permissions.get(), active_permissions.get()); 1917 1918 // Make sure the active permissions contain the default permissions. 1919 adjusted_active = PermissionSet::CreateUnion( 1920 extensions::PermissionsData::GetRequiredPermissions(extension), 1921 adjusted_active.get()); 1922 1923 extensions::PermissionsUpdater perms_updater(profile()); 1924 perms_updater.UpdateActivePermissions(extension, adjusted_active.get()); 1925 } 1926 } 1927 1928 void ExtensionService::CheckPermissionsIncrease(const Extension* extension, 1929 bool is_extension_installed) { 1930 UpdateActivePermissions(extension); 1931 1932 // We keep track of all permissions the user has granted each extension. 1933 // This allows extensions to gracefully support backwards compatibility 1934 // by including unknown permissions in their manifests. When the user 1935 // installs the extension, only the recognized permissions are recorded. 1936 // When the unknown permissions become recognized (e.g., through browser 1937 // upgrade), we can prompt the user to accept these new permissions. 1938 // Extensions can also silently upgrade to less permissions, and then 1939 // silently upgrade to a version that adds these permissions back. 1940 // 1941 // For example, pretend that Chrome 10 includes a permission "omnibox" 1942 // for an API that adds suggestions to the omnibox. An extension can 1943 // maintain backwards compatibility while still having "omnibox" in the 1944 // manifest. If a user installs the extension on Chrome 9, the browser 1945 // will record the permissions it recognized, not including "omnibox." 1946 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome 1947 // will disable the extension and prompt the user to approve the increase 1948 // in privileges. The extension could then release a new version that 1949 // removes the "omnibox" permission. When the user upgrades, Chrome will 1950 // still remember that "omnibox" had been granted, so that if the 1951 // extension once again includes "omnibox" in an upgrade, the extension 1952 // can upgrade without requiring this user's approval. 1953 int disable_reasons = extension_prefs_->GetDisableReasons(extension->id()); 1954 1955 bool auto_grant_permission = 1956 (!is_extension_installed && extension->was_installed_by_default()) || 1957 extensions::ExtensionsBrowserClient::Get()->IsRunningInForcedAppMode(); 1958 // Silently grant all active permissions to default apps only on install. 1959 // After install they should behave like other apps. 1960 // Silently grant all active permissions to apps install in kiosk mode on both 1961 // install and update. 1962 if (auto_grant_permission) 1963 GrantPermissions(extension); 1964 1965 bool is_privilege_increase = false; 1966 // We only need to compare the granted permissions to the current permissions 1967 // if the extension is not allowed to silently increase its permissions. 1968 if (!extensions::PermissionsData::CanSilentlyIncreasePermissions(extension) && 1969 !auto_grant_permission) { 1970 // Add all the recognized permissions if the granted permissions list 1971 // hasn't been initialized yet. 1972 scoped_refptr<PermissionSet> granted_permissions = 1973 extension_prefs_->GetGrantedPermissions(extension->id()); 1974 CHECK(granted_permissions.get()); 1975 1976 // Here, we check if an extension's privileges have increased in a manner 1977 // that requires the user's approval. This could occur because the browser 1978 // upgraded and recognized additional privileges, or an extension upgrades 1979 // to a version that requires additional privileges. 1980 is_privilege_increase = 1981 extensions::PermissionMessageProvider::Get()->IsPrivilegeIncrease( 1982 granted_permissions, 1983 extension->GetActivePermissions().get(), 1984 extension->GetType()); 1985 } 1986 1987 if (is_extension_installed) { 1988 // If the extension was already disabled, suppress any alerts for becoming 1989 // disabled on permissions increase. 1990 bool previously_disabled = 1991 extension_prefs_->IsExtensionDisabled(extension->id()); 1992 // Legacy disabled extensions do not have a disable reason. Infer that if 1993 // there was no permission increase, it was likely disabled by the user. 1994 if (previously_disabled && disable_reasons == Extension::DISABLE_NONE && 1995 !extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { 1996 disable_reasons |= Extension::DISABLE_USER_ACTION; 1997 } 1998 // Extensions that came to us disabled from sync need a similar inference, 1999 // except based on the new version's permissions. 2000 if (previously_disabled && 2001 disable_reasons == Extension::DISABLE_UNKNOWN_FROM_SYNC) { 2002 // Remove the DISABLE_UNKNOWN_FROM_SYNC reason. 2003 extension_prefs_->ClearDisableReasons(extension->id()); 2004 if (!is_privilege_increase) 2005 disable_reasons |= Extension::DISABLE_USER_ACTION; 2006 } 2007 disable_reasons &= ~Extension::DISABLE_UNKNOWN_FROM_SYNC; 2008 } 2009 2010 // Extension has changed permissions significantly. Disable it. A 2011 // notification should be sent by the caller. 2012 if (is_privilege_increase) { 2013 disable_reasons |= Extension::DISABLE_PERMISSIONS_INCREASE; 2014 if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { 2015 RecordPermissionMessagesHistogram( 2016 extension, "Extensions.Permissions_AutoDisable"); 2017 } 2018 extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); 2019 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); 2020 } 2021 if (disable_reasons != Extension::DISABLE_NONE) { 2022 extension_prefs_->AddDisableReason( 2023 extension->id(), 2024 static_cast<Extension::DisableReason>(disable_reasons)); 2025 } 2026 } 2027 2028 void ExtensionService::UpdateActiveExtensionsInCrashReporter() { 2029 std::set<std::string> extension_ids; 2030 for (ExtensionSet::const_iterator iter = extensions_.begin(); 2031 iter != extensions_.end(); ++iter) { 2032 const Extension* extension = iter->get(); 2033 if (!extension->is_theme() && extension->location() != Manifest::COMPONENT) 2034 extension_ids.insert(extension->id()); 2035 } 2036 2037 crash_keys::SetActiveExtensions(extension_ids); 2038 } 2039 2040 ExtensionService::ImportStatus ExtensionService::CheckImports( 2041 const extensions::Extension* extension, 2042 std::list<SharedModuleInfo::ImportInfo>* missing_modules, 2043 std::list<SharedModuleInfo::ImportInfo>* outdated_modules) { 2044 DCHECK(extension); 2045 DCHECK(missing_modules && missing_modules->empty()); 2046 DCHECK(outdated_modules && outdated_modules->empty()); 2047 ImportStatus status = IMPORT_STATUS_OK; 2048 if (SharedModuleInfo::ImportsModules(extension)) { 2049 const std::vector<SharedModuleInfo::ImportInfo>& imports = 2050 SharedModuleInfo::GetImports(extension); 2051 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i; 2052 for (i = imports.begin(); i != imports.end(); ++i) { 2053 Version version_required(i->minimum_version); 2054 const Extension* imported_module = 2055 GetExtensionById(i->extension_id, true); 2056 if (!imported_module) { 2057 if (extension->from_webstore()) { 2058 status = IMPORT_STATUS_UNSATISFIED; 2059 missing_modules->push_back(*i); 2060 } else { 2061 return IMPORT_STATUS_UNRECOVERABLE; 2062 } 2063 } else if (!SharedModuleInfo::IsSharedModule(imported_module)) { 2064 return IMPORT_STATUS_UNRECOVERABLE; 2065 } else if (version_required.IsValid() && 2066 imported_module->version()->CompareTo(version_required) < 0) { 2067 if (imported_module->from_webstore()) { 2068 outdated_modules->push_back(*i); 2069 status = IMPORT_STATUS_UNSATISFIED; 2070 } else { 2071 return IMPORT_STATUS_UNRECOVERABLE; 2072 } 2073 } 2074 } 2075 } 2076 return status; 2077 } 2078 2079 ExtensionService::ImportStatus ExtensionService::SatisfyImports( 2080 const Extension* extension) { 2081 std::list<SharedModuleInfo::ImportInfo> noinstalled; 2082 std::list<SharedModuleInfo::ImportInfo> outdated; 2083 ImportStatus status = CheckImports(extension, &noinstalled, &outdated); 2084 if (status == IMPORT_STATUS_UNRECOVERABLE) 2085 return status; 2086 if (status == IMPORT_STATUS_UNSATISFIED) { 2087 std::list<SharedModuleInfo::ImportInfo>::const_iterator iter; 2088 for (iter = noinstalled.begin(); iter != noinstalled.end(); ++iter) { 2089 pending_extension_manager()->AddFromExtensionImport( 2090 iter->extension_id, 2091 extension_urls::GetWebstoreUpdateUrl(), 2092 IsSharedModule); 2093 } 2094 CheckForUpdatesSoon(); 2095 } 2096 return status; 2097 } 2098 2099 scoped_ptr<const ExtensionSet> 2100 ExtensionService::GetDependentExtensions(const Extension* extension) { 2101 scoped_ptr<ExtensionSet> dependents(new ExtensionSet()); 2102 scoped_ptr<ExtensionSet> set_to_check(new ExtensionSet()); 2103 if (SharedModuleInfo::IsSharedModule(extension)) { 2104 set_to_check->InsertAll(disabled_extensions_); 2105 set_to_check->InsertAll(delayed_installs_); 2106 set_to_check->InsertAll(extensions_); 2107 for (ExtensionSet::const_iterator iter = set_to_check->begin(); 2108 iter != set_to_check->end(); ++iter) { 2109 if (SharedModuleInfo::ImportsExtensionById(iter->get(), 2110 extension->id())) { 2111 dependents->Insert(*iter); 2112 } 2113 } 2114 } 2115 return dependents.PassAs<const ExtensionSet>(); 2116 } 2117 2118 void ExtensionService::PruneSharedModulesOnUninstall( 2119 const Extension* extension) { 2120 if (SharedModuleInfo::ImportsModules(extension)) { 2121 const std::vector<SharedModuleInfo::ImportInfo>& imports = 2122 SharedModuleInfo::GetImports(extension); 2123 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i; 2124 for (i = imports.begin(); i != imports.end(); ++i) { 2125 const Extension* imported_module = 2126 GetExtensionById(i->extension_id, true); 2127 if (imported_module && imported_module->from_webstore()) { 2128 scoped_ptr<const ExtensionSet> dependents = 2129 GetDependentExtensions(imported_module); 2130 if (dependents->size() == 0) { 2131 UninstallExtension(i->extension_id, true, NULL); 2132 } 2133 } 2134 } 2135 } 2136 } 2137 2138 void ExtensionService::OnExtensionInstalled( 2139 const Extension* extension, 2140 const syncer::StringOrdinal& page_ordinal, 2141 bool has_requirement_errors, 2142 extensions::Blacklist::BlacklistState blacklist_state, 2143 bool wait_for_idle) { 2144 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2145 2146 const std::string& id = extension->id(); 2147 bool initial_enable = ShouldEnableOnInstall(extension); 2148 const extensions::PendingExtensionInfo* pending_extension_info = NULL; 2149 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { 2150 if (!pending_extension_info->ShouldAllowInstall(extension)) { 2151 pending_extension_manager()->Remove(id); 2152 2153 LOG(WARNING) << "ShouldAllowInstall() returned false for " 2154 << id << " of type " << extension->GetType() 2155 << " and update URL " 2156 << extensions::ManifestURL::GetUpdateURL(extension).spec() 2157 << "; not installing"; 2158 2159 // Delete the extension directory since we're not going to 2160 // load it. 2161 if (!GetFileTaskRunner()->PostTask( 2162 FROM_HERE, 2163 base::Bind(&extension_file_util::DeleteFile, 2164 extension->path(), true))) { 2165 NOTREACHED(); 2166 } 2167 return; 2168 } 2169 2170 pending_extension_manager()->Remove(id); 2171 } else { 2172 // We explicitly want to re-enable an uninstalled external 2173 // extension; if we're here, that means the user is manually 2174 // installing the extension. 2175 if (IsExternalExtensionUninstalled(id)) { 2176 initial_enable = true; 2177 } 2178 } 2179 2180 // Unsupported requirements overrides the management policy. 2181 if (has_requirement_errors) { 2182 initial_enable = false; 2183 extension_prefs_->AddDisableReason( 2184 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); 2185 // If the extension was disabled because of unsupported requirements but 2186 // now supports all requirements after an update and there are not other 2187 // disable reasons, enable it. 2188 } else if (extension_prefs_->GetDisableReasons(id) == 2189 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { 2190 initial_enable = true; 2191 extension_prefs_->ClearDisableReasons(id); 2192 } 2193 2194 if (blacklist_state == extensions::Blacklist::BLACKLISTED_MALWARE) { 2195 // Installation of a blacklisted extension can happen from sync, policy, 2196 // etc, where to maintain consistency we need to install it, just never 2197 // load it (see AddExtension). Usually it should be the job of callers to 2198 // incercept blacklisted extension earlier (e.g. CrxInstaller, before even 2199 // showing the install dialogue). 2200 extension_prefs()->AcknowledgeBlacklistedExtension(id); 2201 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", 2202 extension->location(), 2203 Manifest::NUM_LOCATIONS); 2204 } 2205 2206 if (!GetInstalledExtension(extension->id())) { 2207 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", 2208 extension->GetType(), 100); 2209 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", 2210 extension->location(), Manifest::NUM_LOCATIONS); 2211 RecordPermissionMessagesHistogram( 2212 extension, "Extensions.Permissions_Install"); 2213 } else { 2214 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", 2215 extension->GetType(), 100); 2216 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", 2217 extension->location(), Manifest::NUM_LOCATIONS); 2218 } 2219 2220 // Certain extension locations are specific enough that we can 2221 // auto-acknowledge any extension that came from one of them. 2222 if (Manifest::IsPolicyLocation(extension->location())) 2223 AcknowledgeExternalExtension(extension->id()); 2224 const Extension::State initial_state = 2225 initial_enable ? Extension::ENABLED : Extension::DISABLED; 2226 const bool blacklisted_for_malware = 2227 blacklist_state == extensions::Blacklist::BLACKLISTED_MALWARE; 2228 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { 2229 extension_prefs_->SetDelayedInstallInfo( 2230 extension, 2231 initial_state, 2232 blacklisted_for_malware, 2233 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, 2234 page_ordinal); 2235 2236 // Transfer ownership of |extension|. 2237 delayed_installs_.Insert(extension); 2238 2239 // Notify observers that app update is available. 2240 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, 2241 OnAppUpdateAvailable(extension)); 2242 return; 2243 } 2244 2245 ImportStatus status = SatisfyImports(extension); 2246 if (installs_delayed_for_gc()) { 2247 extension_prefs_->SetDelayedInstallInfo( 2248 extension, 2249 initial_state, 2250 blacklisted_for_malware, 2251 extensions::ExtensionPrefs::DELAY_REASON_GC, 2252 page_ordinal); 2253 delayed_installs_.Insert(extension); 2254 } else if (status != IMPORT_STATUS_OK) { 2255 if (status == IMPORT_STATUS_UNSATISFIED) { 2256 extension_prefs_->SetDelayedInstallInfo( 2257 extension, 2258 initial_state, 2259 blacklisted_for_malware, 2260 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS, 2261 page_ordinal); 2262 delayed_installs_.Insert(extension); 2263 } 2264 } else { 2265 AddNewOrUpdatedExtension(extension, 2266 initial_state, 2267 blacklist_state, 2268 page_ordinal); 2269 } 2270 } 2271 2272 void ExtensionService::AddNewOrUpdatedExtension( 2273 const Extension* extension, 2274 Extension::State initial_state, 2275 extensions::Blacklist::BlacklistState blacklist_state, 2276 const syncer::StringOrdinal& page_ordinal) { 2277 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2278 const bool blacklisted_for_malware = 2279 blacklist_state == extensions::Blacklist::BLACKLISTED_MALWARE; 2280 extension_prefs_->OnExtensionInstalled(extension, 2281 initial_state, 2282 blacklisted_for_malware, 2283 page_ordinal); 2284 delayed_installs_.Remove(extension->id()); 2285 if (InstallVerifier::NeedsVerification(*extension)) { 2286 extensions::ExtensionSystem::Get(profile_)->install_verifier()->Add( 2287 extension->id(), base::Bind(LogAddVerifiedSuccess)); 2288 } 2289 FinishInstallation(extension); 2290 } 2291 2292 void ExtensionService::MaybeFinishDelayedInstallation( 2293 const std::string& extension_id) { 2294 // Check if the extension already got installed. 2295 if (!delayed_installs_.Contains(extension_id)) 2296 return; 2297 extensions::ExtensionPrefs::DelayReason reason = 2298 extension_prefs_->GetDelayedInstallReason(extension_id); 2299 2300 // Check if the extension is idle. DELAY_REASON_NONE is used for older 2301 // preferences files that will not have set this field but it was previously 2302 // only used for idle updates. 2303 if ((reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE || 2304 reason == extensions::ExtensionPrefs::DELAY_REASON_NONE) && 2305 is_ready() && !IsExtensionIdle(extension_id)) 2306 return; 2307 2308 const Extension* extension = delayed_installs_.GetByID(extension_id); 2309 if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS) { 2310 ImportStatus status = SatisfyImports(extension); 2311 if (status != IMPORT_STATUS_OK) { 2312 if (status == IMPORT_STATUS_UNRECOVERABLE) { 2313 delayed_installs_.Remove(extension_id); 2314 // Make sure no version of the extension is actually installed, (i.e., 2315 // that this delayed install was not an update). 2316 CHECK(!extension_prefs_->GetInstalledExtensionInfo(extension_id).get()); 2317 extension_prefs_->DeleteExtensionPrefs(extension_id); 2318 } 2319 return; 2320 } 2321 } 2322 2323 FinishDelayedInstallation(extension_id); 2324 } 2325 2326 void ExtensionService::FinishDelayedInstallation( 2327 const std::string& extension_id) { 2328 scoped_refptr<const Extension> extension( 2329 GetPendingExtensionUpdate(extension_id)); 2330 CHECK(extension.get()); 2331 delayed_installs_.Remove(extension_id); 2332 2333 if (!extension_prefs_->FinishDelayedInstallInfo(extension_id)) 2334 NOTREACHED(); 2335 2336 FinishInstallation(extension.get()); 2337 } 2338 2339 void ExtensionService::FinishInstallation(const Extension* extension) { 2340 const extensions::Extension* existing_extension = 2341 GetInstalledExtension(extension->id()); 2342 bool is_update = false; 2343 std::string old_name; 2344 if (existing_extension) { 2345 is_update = true; 2346 old_name = existing_extension->name(); 2347 } 2348 extensions::InstalledExtensionInfo details(extension, is_update, old_name); 2349 content::NotificationService::current()->Notify( 2350 chrome::NOTIFICATION_EXTENSION_INSTALLED, 2351 content::Source<Profile>(profile_), 2352 content::Details<const extensions::InstalledExtensionInfo>(&details)); 2353 2354 bool unacknowledged_external = IsUnacknowledgedExternalExtension(extension); 2355 2356 // Unpacked extensions default to allowing file access, but if that has been 2357 // overridden, don't reset the value. 2358 if (Manifest::ShouldAlwaysAllowFileAccess(extension->location()) && 2359 !extension_prefs_->HasAllowFileAccessSetting(extension->id())) { 2360 extension_prefs_->SetAllowFileAccess(extension->id(), true); 2361 } 2362 2363 AddExtension(extension); 2364 2365 // If this is a new external extension that was disabled, alert the user 2366 // so he can reenable it. We do this last so that it has already been 2367 // added to our list of extensions. 2368 if (unacknowledged_external && !is_update) { 2369 UpdateExternalExtensionAlert(); 2370 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", 2371 EXTERNAL_EXTENSION_INSTALLED, 2372 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 2373 if (extensions::ManifestURL::UpdatesFromGallery(extension)) { 2374 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore", 2375 EXTERNAL_EXTENSION_INSTALLED, 2376 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 2377 } else { 2378 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore", 2379 EXTERNAL_EXTENSION_INSTALLED, 2380 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 2381 } 2382 } 2383 2384 // Check extensions that may have been delayed only because this shared module 2385 // was not available. 2386 if (SharedModuleInfo::IsSharedModule(extension)) { 2387 MaybeFinishDelayedInstallations(); 2388 } 2389 } 2390 2391 const Extension* ExtensionService::GetPendingExtensionUpdate( 2392 const std::string& id) const { 2393 return delayed_installs_.GetByID(id); 2394 } 2395 2396 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { 2397 if (!terminated_extensions_.Contains(extension->id())) 2398 terminated_extensions_.Insert(make_scoped_refptr(extension)); 2399 2400 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_TERMINATE); 2401 } 2402 2403 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { 2404 std::string lowercase_id = StringToLowerASCII(id); 2405 const Extension* extension = terminated_extensions_.GetByID(lowercase_id); 2406 terminated_extensions_.Remove(lowercase_id); 2407 if (extension) { 2408 content::NotificationService::current()->Notify( 2409 chrome::NOTIFICATION_EXTENSION_REMOVED, 2410 content::Source<Profile>(profile_), 2411 content::Details<const Extension>(extension)); 2412 } 2413 } 2414 2415 const Extension* ExtensionService::GetTerminatedExtension( 2416 const std::string& id) const { 2417 return GetExtensionById(id, INCLUDE_TERMINATED); 2418 } 2419 2420 const Extension* ExtensionService::GetInstalledExtension( 2421 const std::string& id) const { 2422 int include_mask = INCLUDE_ENABLED | 2423 INCLUDE_DISABLED | 2424 INCLUDE_TERMINATED | 2425 INCLUDE_BLACKLISTED; 2426 return GetExtensionById(id, include_mask); 2427 } 2428 2429 bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) { 2430 // Allow bindings for all packaged extensions and component hosted apps. 2431 const Extension* extension = extensions_.GetExtensionOrAppByURL(url); 2432 return extension && (!extension->is_hosted_app() || 2433 extension->location() == Manifest::COMPONENT); 2434 } 2435 2436 bool ExtensionService::ShouldBlockUrlInBrowserTab(GURL* url) { 2437 const Extension* extension = extensions_.GetExtensionOrAppByURL(*url); 2438 if (extension && extension->is_platform_app()) { 2439 *url = GURL(chrome::kExtensionInvalidRequestURL); 2440 return true; 2441 } 2442 2443 return false; 2444 } 2445 2446 bool ExtensionService::OnExternalExtensionFileFound( 2447 const std::string& id, 2448 const Version* version, 2449 const base::FilePath& path, 2450 Manifest::Location location, 2451 int creation_flags, 2452 bool mark_acknowledged) { 2453 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2454 CHECK(Extension::IdIsValid(id)); 2455 if (extension_prefs_->IsExternalExtensionUninstalled(id)) 2456 return false; 2457 2458 // Before even bothering to unpack, check and see if we already have this 2459 // version. This is important because these extensions are going to get 2460 // installed on every startup. 2461 const Extension* existing = GetExtensionById(id, true); 2462 2463 if (existing) { 2464 // The default apps will have the location set as INTERNAL. Since older 2465 // default apps are installed as EXTERNAL, we override them. However, if the 2466 // app is already installed as internal, then do the version check. 2467 // TODO(grv) : Remove after Q1-2013. 2468 bool is_default_apps_migration = 2469 (location == Manifest::INTERNAL && 2470 Manifest::IsExternalLocation(existing->location())); 2471 2472 if (!is_default_apps_migration) { 2473 DCHECK(version); 2474 2475 switch (existing->version()->CompareTo(*version)) { 2476 case -1: // existing version is older, we should upgrade 2477 break; 2478 case 0: // existing version is same, do nothing 2479 return false; 2480 case 1: // existing version is newer, uh-oh 2481 LOG(WARNING) << "Found external version of extension " << id 2482 << "that is older than current version. Current version " 2483 << "is: " << existing->VersionString() << ". New " 2484 << "version is: " << version->GetString() 2485 << ". Keeping current version."; 2486 return false; 2487 } 2488 } 2489 } 2490 2491 // If the extension is already pending, don't start an install. 2492 if (!pending_extension_manager()->AddFromExternalFile( 2493 id, location, *version, creation_flags, mark_acknowledged)) { 2494 return false; 2495 } 2496 2497 // no client (silent install) 2498 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(this)); 2499 installer->set_install_source(location); 2500 installer->set_expected_id(id); 2501 installer->set_expected_version(*version); 2502 installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE); 2503 installer->set_creation_flags(creation_flags); 2504 #if defined(OS_CHROMEOS) 2505 extensions::InstallLimiter::Get(profile_)->Add(installer, path); 2506 #else 2507 installer->InstallCrx(path); 2508 #endif 2509 2510 // Depending on the source, a new external extension might not need a user 2511 // notification on installation. For such extensions, mark them acknowledged 2512 // now to suppress the notification. 2513 if (mark_acknowledged) 2514 AcknowledgeExternalExtension(id); 2515 2516 return true; 2517 } 2518 2519 scoped_ptr<DictionaryValue> ExtensionService::GetExtensionInfo( 2520 const std::string& extension_id) const { 2521 scoped_ptr<DictionaryValue> dictionary(new DictionaryValue); 2522 const extensions::Extension* extension = extensions_.GetByID(extension_id); 2523 if (extension) { 2524 GURL icon = extensions::ExtensionIconSource::GetIconURL( 2525 extension, extension_misc::EXTENSION_ICON_SMALLISH, 2526 ExtensionIconSet::MATCH_BIGGER, false, NULL); 2527 dictionary->SetString("id", extension_id); 2528 dictionary->SetString("name", extension->name()); 2529 dictionary->SetString("icon", icon.spec()); 2530 } 2531 return dictionary.Pass(); 2532 } 2533 2534 void ExtensionService::ReportExtensionLoadError( 2535 const base::FilePath& extension_path, 2536 const std::string &error, 2537 bool be_noisy) { 2538 content::NotificationService::current()->Notify( 2539 chrome::NOTIFICATION_EXTENSION_LOAD_ERROR, 2540 content::Source<Profile>(profile_), 2541 content::Details<const std::string>(&error)); 2542 2543 std::string path_str = UTF16ToUTF8(extension_path.LossyDisplayName()); 2544 base::string16 message = UTF8ToUTF16(base::StringPrintf( 2545 "Could not load extension from '%s'. %s", 2546 path_str.c_str(), error.c_str())); 2547 ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy); 2548 } 2549 2550 void ExtensionService::DidCreateRenderViewForBackgroundPage( 2551 extensions::ExtensionHost* host) { 2552 OrphanedDevTools::iterator iter = 2553 orphaned_dev_tools_.find(host->extension_id()); 2554 if (iter == orphaned_dev_tools_.end()) 2555 return; 2556 2557 iter->second->ConnectRenderViewHost(host->render_view_host()); 2558 orphaned_dev_tools_.erase(iter); 2559 } 2560 2561 void ExtensionService::Observe(int type, 2562 const content::NotificationSource& source, 2563 const content::NotificationDetails& details) { 2564 switch (type) { 2565 case chrome::NOTIFICATION_APP_TERMINATING: 2566 // Shutdown has started. Don't start any more extension installs. 2567 // (We cannot use ExtensionService::Shutdown() for this because it 2568 // happens too late in browser teardown.) 2569 browser_terminating_ = true; 2570 break; 2571 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: { 2572 if (profile_ != 2573 content::Source<Profile>(source).ptr()->GetOriginalProfile()) { 2574 break; 2575 } 2576 2577 extensions::ExtensionHost* host = 2578 content::Details<extensions::ExtensionHost>(details).ptr(); 2579 2580 // Mark the extension as terminated and Unload it. We want it to 2581 // be in a consistent state: either fully working or not loaded 2582 // at all, but never half-crashed. We do it in a PostTask so 2583 // that other handlers of this notification will still have 2584 // access to the Extension and ExtensionHost. 2585 base::MessageLoop::current()->PostTask( 2586 FROM_HERE, 2587 base::Bind( 2588 &ExtensionService::TrackTerminatedExtension, 2589 AsWeakPtr(), 2590 host->extension())); 2591 break; 2592 } 2593 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { 2594 content::RenderProcessHost* process = 2595 content::Source<content::RenderProcessHost>(source).ptr(); 2596 Profile* host_profile = 2597 Profile::FromBrowserContext(process->GetBrowserContext()); 2598 if (!profile_->IsSameProfile(host_profile->GetOriginalProfile())) 2599 break; 2600 2601 // Extensions need to know the channel for API restrictions. 2602 process->Send(new ExtensionMsg_SetChannel( 2603 extensions::GetCurrentChannel())); 2604 2605 // Platform apps need to know the system font. 2606 scoped_ptr<base::DictionaryValue> fonts(new base::DictionaryValue); 2607 webui::SetFontAndTextDirection(fonts.get()); 2608 std::string font_family, font_size; 2609 fonts->GetString("fontfamily", &font_family); 2610 fonts->GetString("fontsize", &font_size); 2611 process->Send(new ExtensionMsg_SetSystemFont( 2612 font_family, font_size)); 2613 2614 // Valid extension function names, used to setup bindings in renderer. 2615 std::vector<std::string> function_names; 2616 ExtensionFunctionDispatcher::GetAllFunctionNames(&function_names); 2617 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); 2618 2619 // Scripting whitelist. This is modified by tests and must be communicated 2620 // to renderers. 2621 process->Send(new ExtensionMsg_SetScriptingWhitelist( 2622 extensions::ExtensionsClient::Get()->GetScriptingWhitelist())); 2623 2624 // Loaded extensions. 2625 std::vector<ExtensionMsg_Loaded_Params> loaded_extensions; 2626 for (ExtensionSet::const_iterator iter = extensions_.begin(); 2627 iter != extensions_.end(); ++iter) { 2628 // Renderers don't need to know about themes. 2629 if (!(*iter)->is_theme()) 2630 loaded_extensions.push_back(ExtensionMsg_Loaded_Params(iter->get())); 2631 } 2632 process->Send(new ExtensionMsg_Loaded(loaded_extensions)); 2633 break; 2634 } 2635 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { 2636 content::RenderProcessHost* process = 2637 content::Source<content::RenderProcessHost>(source).ptr(); 2638 Profile* host_profile = 2639 Profile::FromBrowserContext(process->GetBrowserContext()); 2640 if (!profile_->IsSameProfile(host_profile->GetOriginalProfile())) 2641 break; 2642 2643 if (process_map_.Contains(process->GetID())) { 2644 // An extension process was terminated, this might have resulted in an 2645 // app or extension becoming idle. 2646 std::set<std::string> extension_ids = 2647 process_map_.GetExtensionsInProcess(process->GetID()); 2648 for (std::set<std::string>::const_iterator it = extension_ids.begin(); 2649 it != extension_ids.end(); ++it) { 2650 if (delayed_installs_.Contains(*it)) { 2651 base::MessageLoop::current()->PostDelayedTask( 2652 FROM_HERE, 2653 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, 2654 AsWeakPtr(), *it), 2655 base::TimeDelta::FromSeconds(kUpdateIdleDelay)); 2656 } 2657 } 2658 } 2659 2660 process_map_.RemoveAllFromProcess(process->GetID()); 2661 BrowserThread::PostTask( 2662 BrowserThread::IO, 2663 FROM_HERE, 2664 base::Bind(&extensions::InfoMap::UnregisterAllExtensionsInProcess, 2665 system_->info_map(), 2666 process->GetID())); 2667 break; 2668 } 2669 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { 2670 // Notify observers that chrome update is available. 2671 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, 2672 OnChromeUpdateAvailable()); 2673 break; 2674 } 2675 2676 default: 2677 NOTREACHED() << "Unexpected notification type."; 2678 } 2679 } 2680 2681 void ExtensionService::OnExtensionInstallPrefChanged() { 2682 IdentifyAlertableExtensions(); 2683 CheckManagementPolicy(); 2684 } 2685 2686 bool ExtensionService::HasApps() const { 2687 return !GetAppIds().empty(); 2688 } 2689 2690 ExtensionIdSet ExtensionService::GetAppIds() const { 2691 ExtensionIdSet result; 2692 for (ExtensionSet::const_iterator it = extensions_.begin(); 2693 it != extensions_.end(); ++it) { 2694 if ((*it)->is_app() && (*it)->location() != Manifest::COMPONENT) 2695 result.insert((*it)->id()); 2696 } 2697 2698 return result; 2699 } 2700 2701 bool ExtensionService::IsBackgroundPageReady(const Extension* extension) const { 2702 if (!extensions::BackgroundInfo::HasPersistentBackgroundPage(extension)) 2703 return true; 2704 ExtensionRuntimeDataMap::const_iterator it = 2705 extension_runtime_data_.find(extension->id()); 2706 return it == extension_runtime_data_.end() ? false : 2707 it->second.background_page_ready; 2708 } 2709 2710 void ExtensionService::SetBackgroundPageReady(const Extension* extension) { 2711 DCHECK(extensions::BackgroundInfo::HasBackgroundPage(extension)); 2712 extension_runtime_data_[extension->id()].background_page_ready = true; 2713 content::NotificationService::current()->Notify( 2714 chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY, 2715 content::Source<const Extension>(extension), 2716 content::NotificationService::NoDetails()); 2717 } 2718 2719 bool ExtensionService::IsBeingUpgraded(const Extension* extension) const { 2720 ExtensionRuntimeDataMap::const_iterator it = 2721 extension_runtime_data_.find(extension->id()); 2722 return it == extension_runtime_data_.end() ? false : 2723 it->second.being_upgraded; 2724 } 2725 2726 void ExtensionService::SetBeingUpgraded(const Extension* extension, 2727 bool value) { 2728 extension_runtime_data_[extension->id()].being_upgraded = value; 2729 } 2730 2731 bool ExtensionService::IsBeingReloaded( 2732 const std::string& extension_id) const { 2733 return ContainsKey(extensions_being_reloaded_, extension_id); 2734 } 2735 2736 void ExtensionService::SetBeingReloaded(const std::string& extension_id, 2737 bool isBeingReloaded) { 2738 if (isBeingReloaded) 2739 extensions_being_reloaded_.insert(extension_id); 2740 else 2741 extensions_being_reloaded_.erase(extension_id); 2742 } 2743 2744 bool ExtensionService::HasUsedWebRequest(const Extension* extension) const { 2745 ExtensionRuntimeDataMap::const_iterator it = 2746 extension_runtime_data_.find(extension->id()); 2747 return it == extension_runtime_data_.end() ? false : 2748 it->second.has_used_webrequest; 2749 } 2750 2751 void ExtensionService::SetHasUsedWebRequest(const Extension* extension, 2752 bool value) { 2753 extension_runtime_data_[extension->id()].has_used_webrequest = value; 2754 } 2755 2756 bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) { 2757 // Extensions installed by policy can't be disabled. So even if a previous 2758 // installation disabled the extension, make sure it is now enabled. 2759 if (system_->management_policy()->MustRemainEnabled(extension, NULL)) 2760 return true; 2761 2762 if (extension_prefs_->IsExtensionDisabled(extension->id())) 2763 return false; 2764 2765 if (FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) { 2766 // External extensions are initially disabled. We prompt the user before 2767 // enabling them. Hosted apps are excepted because they are not dangerous 2768 // (they need to be launched by the user anyway). 2769 if (extension->GetType() != Manifest::TYPE_HOSTED_APP && 2770 Manifest::IsExternalLocation(extension->location()) && 2771 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { 2772 return false; 2773 } 2774 } 2775 2776 return true; 2777 } 2778 2779 bool ExtensionService::IsExtensionIdle(const std::string& extension_id) const { 2780 extensions::ProcessManager* process_manager = system_->process_manager(); 2781 DCHECK(process_manager); 2782 extensions::ExtensionHost* host = 2783 process_manager->GetBackgroundHostForExtension(extension_id); 2784 if (host) 2785 return false; 2786 2787 content::SiteInstance* site_instance = process_manager->GetSiteInstanceForURL( 2788 Extension::GetBaseURLFromExtensionId(extension_id)); 2789 if (site_instance && site_instance->HasProcess()) { 2790 return false; 2791 } 2792 2793 return process_manager->GetRenderViewHostsForExtension(extension_id).empty(); 2794 } 2795 2796 bool ExtensionService::ShouldDelayExtensionUpdate( 2797 const std::string& extension_id, 2798 bool wait_for_idle) const { 2799 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; 2800 2801 // If delayed updates are globally disabled, or just for this extension, 2802 // don't delay. 2803 if (!install_updates_when_idle_ || !wait_for_idle) 2804 return false; 2805 2806 const Extension* old = GetInstalledExtension(extension_id); 2807 // If there is no old extension, this is not an update, so don't delay. 2808 if (!old) 2809 return false; 2810 2811 if (extensions::BackgroundInfo::HasPersistentBackgroundPage(old)) { 2812 // Delay installation if the extension listens for the onUpdateAvailable 2813 // event. 2814 return system_->event_router()->ExtensionHasEventListener( 2815 extension_id, kOnUpdateAvailableEvent); 2816 } else { 2817 // Delay installation if the extension is not idle. 2818 return !IsExtensionIdle(extension_id); 2819 } 2820 } 2821 2822 void ExtensionService::GarbageCollectIsolatedStorage() { 2823 scoped_ptr<base::hash_set<base::FilePath> > active_paths( 2824 new base::hash_set<base::FilePath>()); 2825 for (ExtensionSet::const_iterator it = extensions_.begin(); 2826 it != extensions_.end(); ++it) { 2827 if (extensions::AppIsolationInfo::HasIsolatedStorage(it->get())) { 2828 active_paths->insert(BrowserContext::GetStoragePartitionForSite( 2829 profile_, GetSiteForExtensionId((*it)->id()))->GetPath()); 2830 } 2831 } 2832 2833 DCHECK(!installs_delayed_for_gc()); 2834 set_installs_delayed_for_gc(true); 2835 BrowserContext::GarbageCollectStoragePartitions( 2836 profile_, active_paths.Pass(), 2837 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished, 2838 AsWeakPtr())); 2839 } 2840 2841 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { 2842 set_installs_delayed_for_gc(false); 2843 MaybeFinishDelayedInstallations(); 2844 } 2845 2846 void ExtensionService::MaybeFinishDelayedInstallations() { 2847 std::vector<std::string> to_be_installed; 2848 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); 2849 it != delayed_installs_.end(); 2850 ++it) { 2851 to_be_installed.push_back((*it)->id()); 2852 } 2853 for (std::vector<std::string>::const_iterator it = to_be_installed.begin(); 2854 it != to_be_installed.end(); 2855 ++it) { 2856 MaybeFinishDelayedInstallation(*it); 2857 } 2858 } 2859 2860 void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() { 2861 extension_prefs_->SetNeedsStorageGarbageCollection(true); 2862 } 2863 2864 void ExtensionService::OnBlacklistUpdated() { 2865 blacklist_->GetMalwareIDs( 2866 GenerateInstalledExtensionsSet()->GetIDs(), 2867 base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr())); 2868 } 2869 2870 void ExtensionService::ManageBlacklist(const std::set<std::string>& updated) { 2871 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2872 2873 std::set<std::string> before = blacklisted_extensions_.GetIDs(); 2874 std::set<std::string> no_longer_blacklisted = 2875 base::STLSetDifference<std::set<std::string> >(before, updated); 2876 std::set<std::string> not_yet_blacklisted = 2877 base::STLSetDifference<std::set<std::string> >(updated, before); 2878 2879 for (std::set<std::string>::iterator it = no_longer_blacklisted.begin(); 2880 it != no_longer_blacklisted.end(); ++it) { 2881 scoped_refptr<const Extension> extension = 2882 blacklisted_extensions_.GetByID(*it); 2883 if (!extension.get()) { 2884 NOTREACHED() << "Extension " << *it << " no longer blacklisted, " 2885 << "but it was never blacklisted."; 2886 continue; 2887 } 2888 blacklisted_extensions_.Remove(*it); 2889 extension_prefs_->SetExtensionBlacklisted(extension->id(), false); 2890 AddExtension(extension.get()); 2891 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.UnblacklistInstalled", 2892 extension->location(), 2893 Manifest::NUM_LOCATIONS); 2894 } 2895 2896 for (std::set<std::string>::iterator it = not_yet_blacklisted.begin(); 2897 it != not_yet_blacklisted.end(); ++it) { 2898 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); 2899 if (!extension.get()) { 2900 NOTREACHED() << "Extension " << *it << " needs to be " 2901 << "blacklisted, but it's not installed."; 2902 continue; 2903 } 2904 blacklisted_extensions_.Insert(extension); 2905 extension_prefs_->SetExtensionBlacklisted(extension->id(), true); 2906 UnloadExtension(*it, UnloadedExtensionInfo::REASON_BLACKLIST); 2907 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled", 2908 extension->location(), Manifest::NUM_LOCATIONS); 2909 } 2910 2911 IdentifyAlertableExtensions(); 2912 } 2913 2914 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { 2915 update_observers_.AddObserver(observer); 2916 } 2917 2918 void ExtensionService::RemoveUpdateObserver( 2919 extensions::UpdateObserver* observer) { 2920 update_observers_.RemoveObserver(observer); 2921 } 2922