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/command_line.h" 12 #include "base/metrics/histogram.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/stringprintf.h" 15 #include "base/strings/utf_string_conversions.h" 16 #include "base/threading/sequenced_worker_pool.h" 17 #include "base/threading/thread_restrictions.h" 18 #include "base/time/time.h" 19 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/chrome_notification_types.h" 21 #include "chrome/browser/content_settings/content_settings_custom_extension_provider.h" 22 #include "chrome/browser/content_settings/content_settings_internal_extension_provider.h" 23 #include "chrome/browser/content_settings/host_content_settings_map.h" 24 #include "chrome/browser/extensions/api/content_settings/content_settings_service.h" 25 #include "chrome/browser/extensions/component_loader.h" 26 #include "chrome/browser/extensions/crx_installer.h" 27 #include "chrome/browser/extensions/data_deleter.h" 28 #include "chrome/browser/extensions/extension_action_storage_manager.h" 29 #include "chrome/browser/extensions/extension_assets_manager.h" 30 #include "chrome/browser/extensions/extension_disabled_ui.h" 31 #include "chrome/browser/extensions/extension_error_controller.h" 32 #include "chrome/browser/extensions/extension_install_ui.h" 33 #include "chrome/browser/extensions/extension_special_storage_policy.h" 34 #include "chrome/browser/extensions/extension_sync_service.h" 35 #include "chrome/browser/extensions/extension_util.h" 36 #include "chrome/browser/extensions/external_install_manager.h" 37 #include "chrome/browser/extensions/external_provider_impl.h" 38 #include "chrome/browser/extensions/install_verifier.h" 39 #include "chrome/browser/extensions/installed_loader.h" 40 #include "chrome/browser/extensions/pending_extension_manager.h" 41 #include "chrome/browser/extensions/permissions_updater.h" 42 #include "chrome/browser/extensions/shared_module_service.h" 43 #include "chrome/browser/extensions/unpacked_installer.h" 44 #include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h" 45 #include "chrome/browser/extensions/updater/extension_cache.h" 46 #include "chrome/browser/extensions/updater/extension_downloader.h" 47 #include "chrome/browser/extensions/updater/extension_updater.h" 48 #include "chrome/browser/google/google_brand.h" 49 #include "chrome/browser/profiles/profile.h" 50 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 51 #include "chrome/browser/ui/webui/favicon_source.h" 52 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" 53 #include "chrome/browser/ui/webui/theme_source.h" 54 #include "chrome/common/chrome_switches.h" 55 #include "chrome/common/crash_keys.h" 56 #include "chrome/common/extensions/extension_constants.h" 57 #include "chrome/common/extensions/features/feature_channel.h" 58 #include "chrome/common/extensions/manifest_url_handler.h" 59 #include "chrome/common/url_constants.h" 60 #include "components/crx_file/id_util.h" 61 #include "components/startup_metric_utils/startup_metric_utils.h" 62 #include "content/public/browser/devtools_agent_host.h" 63 #include "content/public/browser/notification_service.h" 64 #include "content/public/browser/render_process_host.h" 65 #include "content/public/browser/storage_partition.h" 66 #include "extensions/browser/event_router.h" 67 #include "extensions/browser/extension_host.h" 68 #include "extensions/browser/extension_prefs.h" 69 #include "extensions/browser/extension_registry.h" 70 #include "extensions/browser/extension_system.h" 71 #include "extensions/browser/install_flag.h" 72 #include "extensions/browser/runtime_data.h" 73 #include "extensions/browser/uninstall_reason.h" 74 #include "extensions/browser/update_observer.h" 75 #include "extensions/common/extension_messages.h" 76 #include "extensions/common/extension_urls.h" 77 #include "extensions/common/feature_switch.h" 78 #include "extensions/common/file_util.h" 79 #include "extensions/common/manifest_constants.h" 80 #include "extensions/common/manifest_handlers/background_info.h" 81 #include "extensions/common/one_shot_event.h" 82 #include "extensions/common/permissions/permission_message_provider.h" 83 #include "extensions/common/permissions/permissions_data.h" 84 85 #if defined(OS_CHROMEOS) 86 #include "chrome/browser/chromeos/extensions/install_limiter.h" 87 #include "storage/browser/fileapi/file_system_backend.h" 88 #include "storage/browser/fileapi/file_system_context.h" 89 #endif 90 91 using content::BrowserContext; 92 using content::BrowserThread; 93 using content::DevToolsAgentHost; 94 using extensions::CrxInstaller; 95 using extensions::Extension; 96 using extensions::ExtensionIdSet; 97 using extensions::ExtensionInfo; 98 using extensions::ExtensionRegistry; 99 using extensions::ExtensionSet; 100 using extensions::FeatureSwitch; 101 using extensions::InstallVerifier; 102 using extensions::ManagementPolicy; 103 using extensions::Manifest; 104 using extensions::PermissionMessage; 105 using extensions::PermissionMessages; 106 using extensions::PermissionSet; 107 using extensions::SharedModuleInfo; 108 using extensions::SharedModuleService; 109 using extensions::UnloadedExtensionInfo; 110 111 namespace errors = extensions::manifest_errors; 112 113 namespace { 114 115 // Wait this many seconds after an extensions becomes idle before updating it. 116 const int kUpdateIdleDelay = 5; 117 118 } // namespace 119 120 // ExtensionService. 121 122 void ExtensionService::CheckExternalUninstall(const std::string& id) { 123 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 124 125 // Check if the providers know about this extension. 126 extensions::ProviderCollection::const_iterator i; 127 for (i = external_extension_providers_.begin(); 128 i != external_extension_providers_.end(); ++i) { 129 DCHECK(i->get()->IsReady()); 130 if (i->get()->HasExtension(id)) 131 return; // Yup, known extension, don't uninstall. 132 } 133 134 // We get the list of external extensions to check from preferences. 135 // It is possible that an extension has preferences but is not loaded. 136 // For example, an extension that requires experimental permissions 137 // will not be loaded if the experimental command line flag is not used. 138 // In this case, do not uninstall. 139 if (!GetInstalledExtension(id)) { 140 // We can't call UninstallExtension with an unloaded/invalid 141 // extension ID. 142 LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension " 143 << "with id: " << id; 144 return; 145 } 146 UninstallExtension(id, 147 extensions::UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION, 148 base::Bind(&base::DoNothing), 149 NULL); 150 } 151 152 void ExtensionService::SetFileTaskRunnerForTesting( 153 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { 154 file_task_runner_ = task_runner; 155 } 156 157 void ExtensionService::ClearProvidersForTesting() { 158 external_extension_providers_.clear(); 159 } 160 161 void ExtensionService::AddProviderForTesting( 162 extensions::ExternalProviderInterface* test_provider) { 163 CHECK(test_provider); 164 external_extension_providers_.push_back( 165 linked_ptr<extensions::ExternalProviderInterface>(test_provider)); 166 } 167 168 void ExtensionService::BlacklistExtensionForTest( 169 const std::string& extension_id) { 170 ExtensionIdSet blocked; 171 ExtensionIdSet unchanged; 172 blocked.insert(extension_id); 173 UpdateBlockedExtensions(blocked, unchanged); 174 } 175 176 bool ExtensionService::OnExternalExtensionUpdateUrlFound( 177 const std::string& id, 178 const std::string& install_parameter, 179 const GURL& update_url, 180 Manifest::Location location, 181 int creation_flags, 182 bool mark_acknowledged) { 183 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 184 CHECK(crx_file::id_util::IdIsValid(id)); 185 186 if (Manifest::IsExternalLocation(location)) { 187 // All extensions that are not user specific can be cached. 188 extensions::ExtensionCache::GetInstance()->AllowCaching(id); 189 } 190 191 const Extension* extension = GetExtensionById(id, true); 192 if (extension) { 193 // Already installed. Skip this install if the current location has 194 // higher priority than |location|. 195 Manifest::Location current = extension->location(); 196 if (current == Manifest::GetHigherPriorityLocation(current, location)) 197 return false; 198 // Otherwise, overwrite the current installation. 199 } 200 201 // Add |id| to the set of pending extensions. If it can not be added, 202 // then there is already a pending record from a higher-priority install 203 // source. In this case, signal that this extension will not be 204 // installed by returning false. 205 if (!pending_extension_manager()->AddFromExternalUpdateUrl( 206 id, 207 install_parameter, 208 update_url, 209 location, 210 creation_flags, 211 mark_acknowledged)) { 212 return false; 213 } 214 215 update_once_all_providers_are_ready_ = true; 216 return true; 217 } 218 219 // static 220 // This function is used to uninstall an extension via sync. The LOG statements 221 // within this function are used to inform the user if the uninstall cannot be 222 // done. 223 bool ExtensionService::UninstallExtensionHelper( 224 ExtensionService* extensions_service, 225 const std::string& extension_id, 226 extensions::UninstallReason reason) { 227 // We can't call UninstallExtension with an invalid extension ID. 228 if (!extensions_service->GetInstalledExtension(extension_id)) { 229 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " 230 << "id: " << extension_id; 231 return false; 232 } 233 234 // The following call to UninstallExtension will not allow an uninstall of a 235 // policy-controlled extension. 236 base::string16 error; 237 if (!extensions_service->UninstallExtension( 238 extension_id, reason, base::Bind(&base::DoNothing), &error)) { 239 LOG(WARNING) << "Cannot uninstall extension with id " << extension_id 240 << ": " << error; 241 return false; 242 } 243 244 return true; 245 } 246 247 ExtensionService::ExtensionService(Profile* profile, 248 const CommandLine* command_line, 249 const base::FilePath& install_directory, 250 extensions::ExtensionPrefs* extension_prefs, 251 extensions::Blacklist* blacklist, 252 bool autoupdate_enabled, 253 bool extensions_enabled, 254 extensions::OneShotEvent* ready) 255 : extensions::Blacklist::Observer(blacklist), 256 profile_(profile), 257 system_(extensions::ExtensionSystem::Get(profile)), 258 extension_prefs_(extension_prefs), 259 blacklist_(blacklist), 260 extension_sync_service_(NULL), 261 registry_(extensions::ExtensionRegistry::Get(profile)), 262 pending_extension_manager_(profile), 263 install_directory_(install_directory), 264 extensions_enabled_(extensions_enabled), 265 show_extensions_prompts_(true), 266 install_updates_when_idle_(true), 267 ready_(ready), 268 update_once_all_providers_are_ready_(false), 269 browser_terminating_(false), 270 installs_delayed_for_gc_(false), 271 is_first_run_(false), 272 shared_module_service_(new extensions::SharedModuleService(profile_)) { 273 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 274 275 // Figure out if extension installation should be enabled. 276 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( 277 *command_line, profile)) 278 extensions_enabled_ = false; 279 280 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 281 content::NotificationService::AllBrowserContextsAndSources()); 282 registrar_.Add(this, 283 extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, 284 content::NotificationService::AllBrowserContextsAndSources()); 285 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 286 content::NotificationService::AllBrowserContextsAndSources()); 287 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, 288 content::NotificationService::AllBrowserContextsAndSources()); 289 registrar_.Add(this, 290 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED, 291 content::Source<Profile>(profile_)); 292 293 extensions::ExtensionManagementFactory::GetForBrowserContext(profile_) 294 ->AddObserver(this); 295 296 // Set up the ExtensionUpdater 297 if (autoupdate_enabled) { 298 int update_frequency = extensions::kDefaultUpdateFrequencySeconds; 299 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { 300 base::StringToInt(command_line->GetSwitchValueASCII( 301 switches::kExtensionsUpdateFrequency), 302 &update_frequency); 303 } 304 updater_.reset(new extensions::ExtensionUpdater( 305 this, 306 extension_prefs, 307 profile->GetPrefs(), 308 profile, 309 update_frequency, 310 extensions::ExtensionCache::GetInstance(), 311 base::Bind(ChromeExtensionDownloaderFactory::CreateForProfile, 312 profile))); 313 } 314 315 component_loader_.reset( 316 new extensions::ComponentLoader(this, 317 profile->GetPrefs(), 318 g_browser_process->local_state(), 319 profile)); 320 321 if (extensions_enabled_) { 322 extensions::ExternalProviderImpl::CreateExternalProviders( 323 this, profile_, &external_extension_providers_); 324 } 325 326 // Set this as the ExtensionService for app sorting to ensure it causes syncs 327 // if required. 328 is_first_run_ = !extension_prefs_->SetAlertSystemFirstRun(); 329 330 error_controller_.reset( 331 new extensions::ExtensionErrorController(profile_, is_first_run_)); 332 external_install_manager_.reset( 333 new extensions::ExternalInstallManager(profile_, is_first_run_)); 334 335 extension_action_storage_manager_.reset( 336 new extensions::ExtensionActionStorageManager(profile_)); 337 338 // How long is the path to the Extensions directory? 339 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.ExtensionRootPathLength", 340 install_directory_.value().length(), 0, 500, 100); 341 } 342 343 const ExtensionSet* ExtensionService::extensions() const { 344 return ®istry_->enabled_extensions(); 345 } 346 347 extensions::PendingExtensionManager* 348 ExtensionService::pending_extension_manager() { 349 return &pending_extension_manager_; 350 } 351 352 ExtensionService::~ExtensionService() { 353 // No need to unload extensions here because they are profile-scoped, and the 354 // profile is in the process of being deleted. 355 356 extensions::ProviderCollection::const_iterator i; 357 for (i = external_extension_providers_.begin(); 358 i != external_extension_providers_.end(); ++i) { 359 extensions::ExternalProviderInterface* provider = i->get(); 360 provider->ServiceShutdown(); 361 } 362 } 363 364 void ExtensionService::Shutdown() { 365 extensions::ExtensionManagementFactory::GetInstance() 366 ->GetForBrowserContext(profile()) 367 ->RemoveObserver(this); 368 system_->management_policy()->UnregisterProvider( 369 shared_module_policy_provider_.get()); 370 } 371 372 const Extension* ExtensionService::GetExtensionById( 373 const std::string& id, bool include_disabled) const { 374 int include_mask = ExtensionRegistry::ENABLED; 375 if (include_disabled) { 376 // Include blacklisted extensions here because there are hundreds of 377 // callers of this function, and many might assume that this includes those 378 // that have been disabled due to blacklisting. 379 include_mask |= ExtensionRegistry::DISABLED | 380 ExtensionRegistry::BLACKLISTED; 381 } 382 return registry_->GetExtensionById(id, include_mask); 383 } 384 385 void ExtensionService::Init() { 386 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 387 388 base::Time begin_time = base::Time::Now(); 389 390 DCHECK(!is_ready()); // Can't redo init. 391 DCHECK_EQ(registry_->enabled_extensions().size(), 0u); 392 393 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 394 if (cmd_line->HasSwitch(switches::kInstallEphemeralAppFromWebstore)) { 395 // The sole purpose of this launch is to install a new extension from CWS 396 // and immediately terminate: loading already installed extensions is 397 // unnecessary and may interfere with the inline install dialog (e.g. if an 398 // extension listens to onStartup and opens a window). 399 SetReadyAndNotifyListeners(); 400 } else { 401 // LoadAllExtensions() calls OnLoadedInstalledExtensions(). 402 component_loader_->LoadAll(); 403 extensions::InstalledLoader(this).LoadAllExtensions(); 404 405 // Attempt to re-enable extensions whose only disable reason is reloading. 406 std::vector<std::string> extensions_to_enable; 407 const ExtensionSet& disabled_extensions = registry_->disabled_extensions(); 408 for (ExtensionSet::const_iterator iter = disabled_extensions.begin(); 409 iter != disabled_extensions.end(); ++iter) { 410 const Extension* e = iter->get(); 411 if (extension_prefs_->GetDisableReasons(e->id()) == 412 Extension::DISABLE_RELOAD) { 413 extensions_to_enable.push_back(e->id()); 414 } 415 } 416 for (std::vector<std::string>::iterator it = extensions_to_enable.begin(); 417 it != extensions_to_enable.end(); ++it) { 418 EnableExtension(*it); 419 } 420 421 // Finish install (if possible) of extensions that were still delayed while 422 // the browser was shut down. 423 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info( 424 extension_prefs_->GetAllDelayedInstallInfo()); 425 for (size_t i = 0; i < delayed_info->size(); ++i) { 426 ExtensionInfo* info = delayed_info->at(i).get(); 427 scoped_refptr<const Extension> extension(NULL); 428 if (info->extension_manifest) { 429 std::string error; 430 extension = Extension::Create( 431 info->extension_path, 432 info->extension_location, 433 *info->extension_manifest, 434 extension_prefs_->GetDelayedInstallCreationFlags( 435 info->extension_id), 436 info->extension_id, 437 &error); 438 if (extension.get()) 439 delayed_installs_.Insert(extension); 440 } 441 } 442 MaybeFinishDelayedInstallations(); 443 444 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2( 445 extension_prefs_->GetAllDelayedInstallInfo()); 446 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", 447 delayed_info2->size() - delayed_info->size()); 448 449 SetReadyAndNotifyListeners(); 450 451 // TODO(erikkay) this should probably be deferred to a future point 452 // rather than running immediately at startup. 453 CheckForExternalUpdates(); 454 455 LoadGreylistFromPrefs(); 456 } 457 458 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", 459 base::Time::Now() - begin_time); 460 } 461 462 void ExtensionService::LoadGreylistFromPrefs() { 463 scoped_ptr<ExtensionSet> all_extensions = 464 registry_->GenerateInstalledExtensionsSet(); 465 466 for (ExtensionSet::const_iterator it = all_extensions->begin(); 467 it != all_extensions->end(); ++it) { 468 extensions::BlacklistState state = 469 extension_prefs_->GetExtensionBlacklistState((*it)->id()); 470 if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY || 471 state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED || 472 state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION) 473 greylist_.Insert(*it); 474 } 475 } 476 477 bool ExtensionService::UpdateExtension(const std::string& id, 478 const base::FilePath& extension_path, 479 bool file_ownership_passed, 480 CrxInstaller** out_crx_installer) { 481 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 482 if (browser_terminating_) { 483 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; 484 // Leak the temp file at extension_path. We don't want to add to the disk 485 // I/O burden at shutdown, we can't rely on the I/O completing anyway, and 486 // the file is in the OS temp directory which should be cleaned up for us. 487 return false; 488 } 489 490 const extensions::PendingExtensionInfo* pending_extension_info = 491 pending_extension_manager()->GetById(id); 492 493 const Extension* extension = GetInstalledExtension(id); 494 if (!pending_extension_info && !extension) { 495 LOG(WARNING) << "Will not update extension " << id 496 << " because it is not installed or pending"; 497 // Delete extension_path since we're not creating a CrxInstaller 498 // that would do it for us. 499 if (!GetFileTaskRunner()->PostTask( 500 FROM_HERE, 501 base::Bind( 502 &extensions::file_util::DeleteFile, extension_path, false))) 503 NOTREACHED(); 504 505 return false; 506 } 507 508 // We want a silent install only for non-pending extensions and 509 // pending extensions that have install_silently set. 510 scoped_ptr<ExtensionInstallPrompt> client; 511 if (pending_extension_info && !pending_extension_info->install_silently()) 512 client.reset(ExtensionInstallUI::CreateInstallPromptWithProfile(profile_)); 513 514 scoped_refptr<CrxInstaller> installer( 515 CrxInstaller::Create(this, client.Pass())); 516 installer->set_expected_id(id); 517 int creation_flags = Extension::NO_FLAGS; 518 if (pending_extension_info) { 519 installer->set_install_source(pending_extension_info->install_source()); 520 if (pending_extension_info->install_silently()) 521 installer->set_allow_silent_install(true); 522 if (pending_extension_info->remote_install()) 523 installer->set_grant_permissions(false); 524 creation_flags = pending_extension_info->creation_flags(); 525 if (pending_extension_info->mark_acknowledged()) 526 external_install_manager_->AcknowledgeExternalExtension(id); 527 } else if (extension) { 528 installer->set_install_source(extension->location()); 529 } 530 // If the extension was installed from or has migrated to the webstore, or 531 // its auto-update URL is from the webstore, treat it as a webstore install. 532 // Note that we ignore some older extensions with blank auto-update URLs 533 // because we are mostly concerned with restrictions on NaCl extensions, 534 // which are newer. 535 if ((extension && extension->from_webstore()) || 536 (extension && extensions::ManifestURL::UpdatesFromGallery(extension)) || 537 (!extension && extension_urls::IsWebstoreUpdateUrl( 538 pending_extension_info->update_url()))) { 539 creation_flags |= Extension::FROM_WEBSTORE; 540 } 541 542 // Bookmark apps being updated is kind of a contradiction, but that's because 543 // we mark the default apps as bookmark apps, and they're hosted in the web 544 // store, thus they can get updated. See http://crbug.com/101605 for more 545 // details. 546 if (extension && extension->from_bookmark()) 547 creation_flags |= Extension::FROM_BOOKMARK; 548 549 if (extension && extension->was_installed_by_default()) 550 creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT; 551 552 if (extension && extension->was_installed_by_oem()) 553 creation_flags |= Extension::WAS_INSTALLED_BY_OEM; 554 555 if (extension && extension->was_installed_by_custodian()) 556 creation_flags |= Extension::WAS_INSTALLED_BY_CUSTODIAN; 557 558 if (extension) { 559 installer->set_is_ephemeral(extension_prefs_->IsEphemeralApp(id)); 560 installer->set_do_not_sync(extension_prefs_->DoNotSync(id)); 561 } 562 563 installer->set_creation_flags(creation_flags); 564 565 installer->set_delete_source(file_ownership_passed); 566 installer->set_install_cause(extension_misc::INSTALL_CAUSE_UPDATE); 567 installer->InstallCrx(extension_path); 568 569 if (out_crx_installer) 570 *out_crx_installer = installer.get(); 571 572 return true; 573 } 574 575 void ExtensionService::ReloadExtensionImpl( 576 // "transient" because the process of reloading may cause the reference 577 // to become invalid. Instead, use |extension_id|, a copy. 578 const std::string& transient_extension_id, 579 bool be_noisy) { 580 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 581 582 // If the extension is already reloading, don't reload again. 583 if (extension_prefs_->GetDisableReasons(transient_extension_id) & 584 Extension::DISABLE_RELOAD) { 585 return; 586 } 587 588 // Ignore attempts to reload a blacklisted extension. Sometimes this can 589 // happen in a convoluted reload sequence triggered by the termination of a 590 // blacklisted extension and a naive attempt to reload it. For an example see 591 // http://crbug.com/373842. 592 if (registry_->blacklisted_extensions().Contains(transient_extension_id)) 593 return; 594 595 base::FilePath path; 596 597 std::string extension_id = transient_extension_id; 598 const Extension* transient_current_extension = 599 GetExtensionById(extension_id, false); 600 601 // Disable the extension if it's loaded. It might not be loaded if it crashed. 602 if (transient_current_extension) { 603 // If the extension has an inspector open for its background page, detach 604 // the inspector and hang onto a cookie for it, so that we can reattach 605 // later. 606 // TODO(yoz): this is not incognito-safe! 607 extensions::ProcessManager* manager = system_->process_manager(); 608 extensions::ExtensionHost* host = 609 manager->GetBackgroundHostForExtension(extension_id); 610 if (host && DevToolsAgentHost::HasFor(host->host_contents())) { 611 // Look for an open inspector for the background page. 612 scoped_refptr<DevToolsAgentHost> agent_host = 613 DevToolsAgentHost::GetOrCreateFor(host->host_contents()); 614 agent_host->DisconnectWebContents(); 615 orphaned_dev_tools_[extension_id] = agent_host; 616 } 617 618 path = transient_current_extension->path(); 619 // BeingUpgraded is set back to false when the extension is added. 620 system_->runtime_data()->SetBeingUpgraded(transient_current_extension, 621 true); 622 DisableExtension(extension_id, Extension::DISABLE_RELOAD); 623 reloading_extensions_.insert(extension_id); 624 } else { 625 std::map<std::string, base::FilePath>::const_iterator iter = 626 unloaded_extension_paths_.find(extension_id); 627 if (iter == unloaded_extension_paths_.end()) { 628 return; 629 } 630 path = unloaded_extension_paths_[extension_id]; 631 } 632 633 transient_current_extension = NULL; 634 635 if (delayed_installs_.Contains(extension_id)) { 636 FinishDelayedInstallation(extension_id); 637 return; 638 } 639 640 // If we're reloading a component extension, use the component extension 641 // loader's reloader. 642 if (component_loader_->Exists(extension_id)) { 643 component_loader_->Reload(extension_id); 644 return; 645 } 646 647 // Check the installed extensions to see if what we're reloading was already 648 // installed. 649 scoped_ptr<ExtensionInfo> installed_extension( 650 extension_prefs_->GetInstalledExtensionInfo(extension_id)); 651 if (installed_extension.get() && 652 installed_extension->extension_manifest.get()) { 653 extensions::InstalledLoader(this).Load(*installed_extension, false); 654 } else { 655 // Otherwise, the extension is unpacked (location LOAD). 656 // We should always be able to remember the extension's path. If it's not in 657 // the map, someone failed to update |unloaded_extension_paths_|. 658 CHECK(!path.empty()); 659 scoped_refptr<extensions::UnpackedInstaller> unpacked_installer = 660 extensions::UnpackedInstaller::Create(this); 661 unpacked_installer->set_be_noisy_on_failure(be_noisy); 662 unpacked_installer->Load(path); 663 } 664 } 665 666 void ExtensionService::ReloadExtension(const std::string& extension_id) { 667 ReloadExtensionImpl(extension_id, true); // be_noisy 668 } 669 670 void ExtensionService::ReloadExtensionWithQuietFailure( 671 const std::string& extension_id) { 672 ReloadExtensionImpl(extension_id, false); // be_noisy 673 } 674 675 bool ExtensionService::UninstallExtension( 676 // "transient" because the process of uninstalling may cause the reference 677 // to become invalid. Instead, use |extenson->id()|. 678 const std::string& transient_extension_id, 679 extensions::UninstallReason reason, 680 const base::Closure& deletion_done_callback, 681 base::string16* error) { 682 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 683 684 scoped_refptr<const Extension> extension = 685 GetInstalledExtension(transient_extension_id); 686 687 // Callers should not send us nonexistent extensions. 688 CHECK(extension.get()); 689 690 // Policy change which triggers an uninstall will always set 691 // |external_uninstall| to true so this is the only way to uninstall 692 // managed extensions. 693 // Shared modules being uninstalled will also set |external_uninstall| to true 694 // so that we can guarantee users don't uninstall a shared module. 695 // (crbug.com/273300) 696 // TODO(rdevlin.cronin): This is probably not right. We should do something 697 // else, like include an enum IS_INTERNAL_UNINSTALL or IS_USER_UNINSTALL so 698 // we don't do this. 699 bool external_uninstall = 700 (reason == extensions::UNINSTALL_REASON_INTERNAL_MANAGEMENT) || 701 (reason == extensions::UNINSTALL_REASON_REINSTALL) || 702 (reason == extensions::UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION) || 703 (reason == extensions::UNINSTALL_REASON_ORPHANED_SHARED_MODULE) || 704 (reason == extensions::UNINSTALL_REASON_SYNC && 705 extension->was_installed_by_custodian()); 706 if (!external_uninstall && 707 !system_->management_policy()->UserMayModifySettings( 708 extension.get(), error)) { 709 content::NotificationService::current()->Notify( 710 extensions::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, 711 content::Source<Profile>(profile_), 712 content::Details<const Extension>(extension.get())); 713 return false; 714 } 715 716 syncer::SyncChange sync_change; 717 // Don't sync the uninstall if we're going to reinstall the extension 718 // momentarily. 719 if (extension_sync_service_ && 720 reason != extensions::UNINSTALL_REASON_REINSTALL) { 721 sync_change = extension_sync_service_->PrepareToSyncUninstallExtension( 722 extension.get(), is_ready()); 723 } 724 725 system_->install_verifier()->Remove(extension->id()); 726 727 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", 728 extension->GetType(), 100); 729 RecordPermissionMessagesHistogram(extension.get(), 730 "Extensions.Permissions_Uninstall2"); 731 732 // Unload before doing more cleanup to ensure that nothing is hanging on to 733 // any of these resources. 734 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UNINSTALL); 735 736 // Tell the backend to start deleting installed extensions on the file thread. 737 if (!Manifest::IsUnpackedLocation(extension->location())) { 738 if (!GetFileTaskRunner()->PostTask( 739 FROM_HERE, 740 base::Bind(&ExtensionService::UninstallExtensionOnFileThread, 741 extension->id(), 742 profile_, 743 install_directory_, 744 extension->path()))) 745 NOTREACHED(); 746 } 747 748 extensions::DataDeleter::StartDeleting( 749 profile_, extension.get(), deletion_done_callback); 750 751 UntrackTerminatedExtension(extension->id()); 752 753 // Notify interested parties that we've uninstalled this extension. 754 content::NotificationService::current()->Notify( 755 extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, 756 content::Source<Profile>(profile_), 757 content::Details<const Extension>(extension.get())); 758 ExtensionRegistry::Get(profile_) 759 ->TriggerOnUninstalled(extension.get(), reason); 760 761 if (sync_change.IsValid()) { 762 extension_sync_service_->ProcessSyncUninstallExtension(extension->id(), 763 sync_change); 764 } 765 766 delayed_installs_.Remove(extension->id()); 767 768 extension_prefs_->OnExtensionUninstalled( 769 extension->id(), extension->location(), external_uninstall); 770 771 // Track the uninstallation. 772 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); 773 774 return true; 775 } 776 777 // static 778 void ExtensionService::UninstallExtensionOnFileThread( 779 const std::string& id, 780 Profile* profile, 781 const base::FilePath& install_dir, 782 const base::FilePath& extension_path) { 783 extensions::ExtensionAssetsManager* assets_manager = 784 extensions::ExtensionAssetsManager::GetInstance(); 785 assets_manager->UninstallExtension(id, profile, install_dir, extension_path); 786 } 787 788 bool ExtensionService::IsExtensionEnabled( 789 const std::string& extension_id) const { 790 if (registry_->enabled_extensions().Contains(extension_id) || 791 registry_->terminated_extensions().Contains(extension_id)) { 792 return true; 793 } 794 795 if (registry_->disabled_extensions().Contains(extension_id) || 796 registry_->blacklisted_extensions().Contains(extension_id)) { 797 return false; 798 } 799 800 // If the extension hasn't been loaded yet, check the prefs for it. Assume 801 // enabled unless otherwise noted. 802 return !extension_prefs_->IsExtensionDisabled(extension_id) && 803 !extension_prefs_->IsExtensionBlacklisted(extension_id) && 804 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); 805 } 806 807 void ExtensionService::EnableExtension(const std::string& extension_id) { 808 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 809 810 if (IsExtensionEnabled(extension_id)) 811 return; 812 const Extension* extension = 813 registry_->disabled_extensions().GetByID(extension_id); 814 815 ManagementPolicy* policy = system_->management_policy(); 816 if (extension && policy->MustRemainDisabled(extension, NULL, NULL)) { 817 UMA_HISTOGRAM_COUNTS_100("Extensions.EnableDeniedByPolicy", 1); 818 return; 819 } 820 821 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); 822 extension_prefs_->ClearDisableReasons(extension_id); 823 824 // This can happen if sync enables an extension that is not 825 // installed yet. 826 if (!extension) 827 return; 828 829 // Move it over to the enabled list. 830 registry_->AddEnabled(make_scoped_refptr(extension)); 831 registry_->RemoveDisabled(extension->id()); 832 833 NotifyExtensionLoaded(extension); 834 835 // Notify listeners that the extension was enabled. 836 content::NotificationService::current()->Notify( 837 extensions::NOTIFICATION_EXTENSION_ENABLED, 838 content::Source<Profile>(profile_), 839 content::Details<const Extension>(extension)); 840 841 if (extension_sync_service_) 842 extension_sync_service_->SyncEnableExtension(*extension); 843 } 844 845 void ExtensionService::DisableExtension( 846 const std::string& extension_id, 847 Extension::DisableReason disable_reason) { 848 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 849 850 // The extension may have been disabled already. Just add a disable reason. 851 if (!IsExtensionEnabled(extension_id)) { 852 extension_prefs_->AddDisableReason(extension_id, disable_reason); 853 return; 854 } 855 856 const Extension* extension = GetInstalledExtension(extension_id); 857 // |extension| can be NULL if sync disables an extension that is not 858 // installed yet. 859 // EXTERNAL_COMPONENT extensions are not generally modifiable by users, but 860 // can be uninstalled by the browser if the user sets extension-specific 861 // preferences. 862 if (extension && 863 disable_reason != Extension::DISABLE_RELOAD && 864 !system_->management_policy()->UserMayModifySettings(extension, NULL) && 865 extension->location() != Manifest::EXTERNAL_COMPONENT) { 866 return; 867 } 868 869 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); 870 extension_prefs_->AddDisableReason(extension_id, disable_reason); 871 872 int include_mask = 873 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::DISABLED; 874 extension = registry_->GetExtensionById(extension_id, include_mask); 875 if (!extension) 876 return; 877 878 // The extension is either enabled or terminated. 879 DCHECK(registry_->enabled_extensions().Contains(extension->id()) || 880 registry_->terminated_extensions().Contains(extension->id())); 881 882 // Move it over to the disabled list. Don't send a second unload notification 883 // for terminated extensions being disabled. 884 registry_->AddDisabled(make_scoped_refptr(extension)); 885 if (registry_->enabled_extensions().Contains(extension->id())) { 886 registry_->RemoveEnabled(extension->id()); 887 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::REASON_DISABLE); 888 } else { 889 registry_->RemoveTerminated(extension->id()); 890 } 891 892 if (extension_sync_service_) 893 extension_sync_service_->SyncDisableExtension(*extension); 894 } 895 896 void ExtensionService::DisableUserExtensions( 897 const std::vector<std::string>& except_ids) { 898 extensions::ManagementPolicy* management_policy = 899 system_->management_policy(); 900 extensions::ExtensionList to_disable; 901 902 const ExtensionSet& enabled_set = registry_->enabled_extensions(); 903 for (ExtensionSet::const_iterator extension = enabled_set.begin(); 904 extension != enabled_set.end(); ++extension) { 905 if (management_policy->UserMayModifySettings(extension->get(), NULL)) 906 to_disable.push_back(*extension); 907 } 908 const ExtensionSet& terminated_set = registry_->terminated_extensions(); 909 for (ExtensionSet::const_iterator extension = terminated_set.begin(); 910 extension != terminated_set.end(); ++extension) { 911 if (management_policy->UserMayModifySettings(extension->get(), NULL)) 912 to_disable.push_back(*extension); 913 } 914 915 for (extensions::ExtensionList::const_iterator extension = to_disable.begin(); 916 extension != to_disable.end(); ++extension) { 917 if ((*extension)->was_installed_by_default() && 918 extension_urls::IsWebstoreUpdateUrl( 919 extensions::ManifestURL::GetUpdateURL(extension->get()))) 920 continue; 921 const std::string& id = (*extension)->id(); 922 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) 923 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); 924 } 925 } 926 927 void ExtensionService::GrantPermissionsAndEnableExtension( 928 const Extension* extension) { 929 GrantPermissions(extension); 930 RecordPermissionMessagesHistogram(extension, 931 "Extensions.Permissions_ReEnable2"); 932 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); 933 EnableExtension(extension->id()); 934 } 935 936 void ExtensionService::GrantPermissions(const Extension* extension) { 937 CHECK(extension); 938 extensions::PermissionsUpdater(profile()).GrantActivePermissions(extension); 939 } 940 941 // static 942 void ExtensionService::RecordPermissionMessagesHistogram( 943 const Extension* extension, const char* histogram) { 944 // Since this is called from multiple sources, and since the histogram macros 945 // use statics, we need to manually lookup the histogram ourselves. 946 base::HistogramBase* counter = base::LinearHistogram::FactoryGet( 947 histogram, 948 1, 949 PermissionMessage::kEnumBoundary, 950 PermissionMessage::kEnumBoundary + 1, 951 base::HistogramBase::kUmaTargetedHistogramFlag); 952 953 PermissionMessages permissions = 954 extension->permissions_data()->GetPermissionMessages(); 955 if (permissions.empty()) { 956 counter->Add(PermissionMessage::kNone); 957 } else { 958 for (PermissionMessages::iterator it = permissions.begin(); 959 it != permissions.end(); ++it) 960 counter->Add(it->id()); 961 } 962 } 963 964 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) { 965 // The URLRequestContexts need to be first to know that the extension 966 // was loaded, otherwise a race can arise where a renderer that is created 967 // for the extension may try to load an extension URL with an extension id 968 // that the request context doesn't yet know about. The profile is responsible 969 // for ensuring its URLRequestContexts appropriately discover the loaded 970 // extension. 971 system_->RegisterExtensionWithRequestContexts(extension); 972 973 // Tell renderers about the new extension, unless it's a theme (renderers 974 // don't need to know about themes). 975 if (!extension->is_theme()) { 976 for (content::RenderProcessHost::iterator i( 977 content::RenderProcessHost::AllHostsIterator()); 978 !i.IsAtEnd(); i.Advance()) { 979 content::RenderProcessHost* host = i.GetCurrentValue(); 980 Profile* host_profile = 981 Profile::FromBrowserContext(host->GetBrowserContext()); 982 if (host_profile->GetOriginalProfile() == 983 profile_->GetOriginalProfile()) { 984 std::vector<ExtensionMsg_Loaded_Params> loaded_extensions( 985 1, ExtensionMsg_Loaded_Params(extension)); 986 host->Send( 987 new ExtensionMsg_Loaded(loaded_extensions)); 988 } 989 } 990 } 991 992 // Tell subsystems that use the EXTENSION_LOADED notification about the new 993 // extension. 994 // 995 // NOTE: It is important that this happen after notifying the renderers about 996 // the new extensions so that if we navigate to an extension URL in 997 // ExtensionRegistryObserver::OnLoaded or 998 // NOTIFICATION_EXTENSION_LOADED_DEPRECATED, the 999 // renderer is guaranteed to know about it. 1000 registry_->TriggerOnLoaded(extension); 1001 1002 content::NotificationService::current()->Notify( 1003 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 1004 content::Source<Profile>(profile_), 1005 content::Details<const Extension>(extension)); 1006 1007 // TODO(kalman): Convert ExtensionSpecialStoragePolicy to a 1008 // BrowserContextKeyedService and use ExtensionRegistryObserver. 1009 profile_->GetExtensionSpecialStoragePolicy()-> 1010 GrantRightsForExtension(extension); 1011 1012 // TODO(kalman): This is broken. The crash reporter is process-wide so doesn't 1013 // work properly multi-profile. Besides which, it should be using 1014 // ExtensionRegistryObserver. See http://crbug.com/355029. 1015 UpdateActiveExtensionsInCrashReporter(); 1016 1017 const extensions::PermissionsData* permissions_data = 1018 extension->permissions_data(); 1019 1020 // If the extension has permission to load chrome://favicon/ resources we need 1021 // to make sure that the FaviconSource is registered with the 1022 // ChromeURLDataManager. 1023 if (permissions_data->HasHostPermission(GURL(chrome::kChromeUIFaviconURL))) { 1024 FaviconSource* favicon_source = new FaviconSource(profile_, 1025 FaviconSource::FAVICON); 1026 content::URLDataSource::Add(profile_, favicon_source); 1027 } 1028 1029 // Same for chrome://theme/ resources. 1030 if (permissions_data->HasHostPermission(GURL(chrome::kChromeUIThemeURL))) { 1031 ThemeSource* theme_source = new ThemeSource(profile_); 1032 content::URLDataSource::Add(profile_, theme_source); 1033 } 1034 1035 // Same for chrome://thumb/ resources. 1036 if (permissions_data->HasHostPermission( 1037 GURL(chrome::kChromeUIThumbnailURL))) { 1038 ThumbnailSource* thumbnail_source = new ThumbnailSource(profile_, false); 1039 content::URLDataSource::Add(profile_, thumbnail_source); 1040 } 1041 } 1042 1043 void ExtensionService::NotifyExtensionUnloaded( 1044 const Extension* extension, 1045 UnloadedExtensionInfo::Reason reason) { 1046 UnloadedExtensionInfo details(extension, reason); 1047 1048 registry_->TriggerOnUnloaded(extension, reason); 1049 1050 content::NotificationService::current()->Notify( 1051 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 1052 content::Source<Profile>(profile_), 1053 content::Details<UnloadedExtensionInfo>(&details)); 1054 1055 for (content::RenderProcessHost::iterator i( 1056 content::RenderProcessHost::AllHostsIterator()); 1057 !i.IsAtEnd(); i.Advance()) { 1058 content::RenderProcessHost* host = i.GetCurrentValue(); 1059 Profile* host_profile = 1060 Profile::FromBrowserContext(host->GetBrowserContext()); 1061 if (host_profile->GetOriginalProfile() == profile_->GetOriginalProfile()) 1062 host->Send(new ExtensionMsg_Unloaded(extension->id())); 1063 } 1064 1065 system_->UnregisterExtensionWithRequestContexts(extension->id(), reason); 1066 1067 // TODO(kalman): Convert ExtensionSpecialStoragePolicy to a 1068 // BrowserContextKeyedService and use ExtensionRegistryObserver. 1069 profile_->GetExtensionSpecialStoragePolicy()-> 1070 RevokeRightsForExtension(extension); 1071 1072 #if defined(OS_CHROMEOS) 1073 // Revoke external file access for the extension from its file system context. 1074 // It is safe to access the extension's storage partition at this point. The 1075 // storage partition may get destroyed only after the extension gets unloaded. 1076 GURL site = 1077 extensions::util::GetSiteForExtensionId(extension->id(), profile_); 1078 storage::FileSystemContext* filesystem_context = 1079 BrowserContext::GetStoragePartitionForSite(profile_, site) 1080 ->GetFileSystemContext(); 1081 if (filesystem_context && filesystem_context->external_backend()) { 1082 filesystem_context->external_backend()-> 1083 RevokeAccessForExtension(extension->id()); 1084 } 1085 #endif 1086 1087 // TODO(kalman): This is broken. The crash reporter is process-wide so doesn't 1088 // work properly multi-profile. Besides which, it should be using 1089 // ExtensionRegistryObserver::OnExtensionLoaded. See http://crbug.com/355029. 1090 UpdateActiveExtensionsInCrashReporter(); 1091 } 1092 1093 content::BrowserContext* ExtensionService::GetBrowserContext() const { 1094 // Implemented in the .cc file to avoid adding a profile.h dependency to 1095 // extension_service.h. 1096 return profile_; 1097 } 1098 1099 bool ExtensionService::is_ready() { 1100 return ready_->is_signaled(); 1101 } 1102 1103 base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() { 1104 if (file_task_runner_.get()) 1105 return file_task_runner_.get(); 1106 1107 // We should be able to interrupt any part of extension install process during 1108 // shutdown. SKIP_ON_SHUTDOWN ensures that not started extension install tasks 1109 // will be ignored/deleted while we will block on started tasks. 1110 std::string token("ext_install-"); 1111 token.append(profile_->GetPath().AsUTF8Unsafe()); 1112 file_task_runner_ = BrowserThread::GetBlockingPool()-> 1113 GetSequencedTaskRunnerWithShutdownBehavior( 1114 BrowserThread::GetBlockingPool()->GetNamedSequenceToken(token), 1115 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 1116 return file_task_runner_.get(); 1117 } 1118 1119 void ExtensionService::CheckManagementPolicy() { 1120 std::vector<std::string> to_unload; 1121 std::map<std::string, Extension::DisableReason> to_disable; 1122 1123 // Loop through the extensions list, finding extensions we need to unload or 1124 // disable. 1125 const ExtensionSet& extensions = registry_->enabled_extensions(); 1126 for (ExtensionSet::const_iterator iter = extensions.begin(); 1127 iter != extensions.end(); ++iter) { 1128 const Extension* extension = (iter->get()); 1129 if (!system_->management_policy()->UserMayLoad(extension, NULL)) 1130 to_unload.push_back(extension->id()); 1131 Extension::DisableReason disable_reason = Extension::DISABLE_NONE; 1132 if (system_->management_policy()->MustRemainDisabled( 1133 extension, &disable_reason, NULL)) 1134 to_disable[extension->id()] = disable_reason; 1135 } 1136 1137 for (size_t i = 0; i < to_unload.size(); ++i) 1138 UnloadExtension(to_unload[i], UnloadedExtensionInfo::REASON_DISABLE); 1139 1140 for (std::map<std::string, Extension::DisableReason>::const_iterator i = 1141 to_disable.begin(); i != to_disable.end(); ++i) 1142 DisableExtension(i->first, i->second); 1143 } 1144 1145 void ExtensionService::CheckForUpdatesSoon() { 1146 // This can legitimately happen in unit tests. 1147 if (!updater_.get()) 1148 return; 1149 1150 if (AreAllExternalProvidersReady()) { 1151 updater_->CheckSoon(); 1152 } else { 1153 // Sync can start updating before all the external providers are ready 1154 // during startup. Start the update as soon as those providers are ready, 1155 // but not before. 1156 update_once_all_providers_are_ready_ = true; 1157 } 1158 } 1159 1160 // Some extensions will autoupdate themselves externally from Chrome. These 1161 // are typically part of some larger client application package. To support 1162 // these, the extension will register its location in the the preferences file 1163 // (and also, on Windows, in the registry) and this code will periodically 1164 // check that location for a .crx file, which it will then install locally if 1165 // a new version is available. 1166 // Errors are reported through ExtensionErrorReporter. Succcess is not 1167 // reported. 1168 void ExtensionService::CheckForExternalUpdates() { 1169 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1170 1171 // Note that this installation is intentionally silent (since it didn't 1172 // go through the front-end). Extensions that are registered in this 1173 // way are effectively considered 'pre-bundled', and so implicitly 1174 // trusted. In general, if something has HKLM or filesystem access, 1175 // they could install an extension manually themselves anyway. 1176 1177 // Ask each external extension provider to give us a call back for each 1178 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. 1179 extensions::ProviderCollection::const_iterator i; 1180 for (i = external_extension_providers_.begin(); 1181 i != external_extension_providers_.end(); ++i) { 1182 extensions::ExternalProviderInterface* provider = i->get(); 1183 provider->VisitRegisteredExtension(); 1184 } 1185 1186 // Do any required work that we would have done after completion of all 1187 // providers. 1188 if (external_extension_providers_.empty()) 1189 OnAllExternalProvidersReady(); 1190 } 1191 1192 void ExtensionService::OnExternalProviderReady( 1193 const extensions::ExternalProviderInterface* provider) { 1194 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1195 CHECK(provider->IsReady()); 1196 1197 // An external provider has finished loading. We only take action 1198 // if all of them are finished. So we check them first. 1199 if (AreAllExternalProvidersReady()) 1200 OnAllExternalProvidersReady(); 1201 } 1202 1203 bool ExtensionService::AreAllExternalProvidersReady() const { 1204 extensions::ProviderCollection::const_iterator i; 1205 for (i = external_extension_providers_.begin(); 1206 i != external_extension_providers_.end(); ++i) { 1207 if (!i->get()->IsReady()) 1208 return false; 1209 } 1210 return true; 1211 } 1212 1213 void ExtensionService::OnAllExternalProvidersReady() { 1214 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1215 base::TimeDelta elapsed = base::Time::Now() - profile_->GetStartTime(); 1216 UMA_HISTOGRAM_TIMES("Extension.ExternalProvidersReadyAfter", elapsed); 1217 1218 // Install any pending extensions. 1219 if (update_once_all_providers_are_ready_ && updater()) { 1220 update_once_all_providers_are_ready_ = false; 1221 extensions::ExtensionUpdater::CheckParams params; 1222 params.callback = external_updates_finished_callback_; 1223 updater()->CheckNow(params); 1224 } 1225 1226 // Uninstall all the unclaimed extensions. 1227 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> extensions_info( 1228 extension_prefs_->GetInstalledExtensionsInfo()); 1229 for (size_t i = 0; i < extensions_info->size(); ++i) { 1230 ExtensionInfo* info = extensions_info->at(i).get(); 1231 if (Manifest::IsExternalLocation(info->extension_location)) 1232 CheckExternalUninstall(info->extension_id); 1233 } 1234 1235 error_controller_->ShowErrorIfNeeded(); 1236 1237 external_install_manager_->UpdateExternalExtensionAlert(); 1238 } 1239 1240 void ExtensionService::UnloadExtension( 1241 const std::string& extension_id, 1242 UnloadedExtensionInfo::Reason reason) { 1243 // Make sure the extension gets deleted after we return from this function. 1244 int include_mask = 1245 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::TERMINATED; 1246 scoped_refptr<const Extension> extension( 1247 registry_->GetExtensionById(extension_id, include_mask)); 1248 1249 // This method can be called via PostTask, so the extension may have been 1250 // unloaded by the time this runs. 1251 if (!extension.get()) { 1252 // In case the extension may have crashed/uninstalled. Allow the profile to 1253 // clean up its RequestContexts. 1254 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); 1255 return; 1256 } 1257 1258 // Keep information about the extension so that we can reload it later 1259 // even if it's not permanently installed. 1260 unloaded_extension_paths_[extension->id()] = extension->path(); 1261 1262 // Clean up if the extension is meant to be enabled after a reload. 1263 reloading_extensions_.erase(extension->id()); 1264 1265 if (registry_->disabled_extensions().Contains(extension->id())) { 1266 registry_->RemoveDisabled(extension->id()); 1267 // Make sure the profile cleans up its RequestContexts when an already 1268 // disabled extension is unloaded (since they are also tracking the disabled 1269 // extensions). 1270 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); 1271 // Don't send the unloaded notification. It was sent when the extension 1272 // was disabled. 1273 } else { 1274 // Remove the extension from the enabled list. 1275 registry_->RemoveEnabled(extension->id()); 1276 NotifyExtensionUnloaded(extension.get(), reason); 1277 } 1278 1279 content::NotificationService::current()->Notify( 1280 extensions::NOTIFICATION_EXTENSION_REMOVED, 1281 content::Source<Profile>(profile_), 1282 content::Details<const Extension>(extension.get())); 1283 } 1284 1285 void ExtensionService::RemoveComponentExtension( 1286 const std::string& extension_id) { 1287 scoped_refptr<const Extension> extension( 1288 GetExtensionById(extension_id, false)); 1289 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); 1290 if (extension.get()) { 1291 content::NotificationService::current()->Notify( 1292 extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, 1293 content::Source<Profile>(profile_), 1294 content::Details<const Extension>(extension.get())); 1295 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled( 1296 extension.get(), extensions::UNINSTALL_REASON_INTERNAL_MANAGEMENT); 1297 } 1298 } 1299 1300 void ExtensionService::UnloadAllExtensionsForTest() { 1301 UnloadAllExtensionsInternal(); 1302 } 1303 1304 void ExtensionService::ReloadExtensionsForTest() { 1305 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit 1306 // warning about calling test code in production. 1307 UnloadAllExtensionsInternal(); 1308 component_loader_->LoadAll(); 1309 extensions::InstalledLoader(this).LoadAllExtensions(); 1310 // Don't call SetReadyAndNotifyListeners() since tests call this multiple 1311 // times. 1312 } 1313 1314 void ExtensionService::SetReadyAndNotifyListeners() { 1315 ready_->Signal(); 1316 content::NotificationService::current()->Notify( 1317 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 1318 content::Source<Profile>(profile_), 1319 content::NotificationService::NoDetails()); 1320 } 1321 1322 void ExtensionService::OnLoadedInstalledExtensions() { 1323 if (updater_) 1324 updater_->Start(); 1325 1326 OnBlacklistUpdated(); 1327 } 1328 1329 void ExtensionService::AddExtension(const Extension* extension) { 1330 // TODO(jstritar): We may be able to get rid of this branch by overriding the 1331 // default extension state to DISABLED when the --disable-extensions flag 1332 // is set (http://crbug.com/29067). 1333 if (!extensions_enabled() && 1334 !extension->is_theme() && 1335 extension->location() != Manifest::COMPONENT && 1336 !Manifest::IsExternalLocation(extension->location())) { 1337 return; 1338 } 1339 1340 bool is_extension_upgrade = false; 1341 bool is_extension_installed = false; 1342 const Extension* old = GetInstalledExtension(extension->id()); 1343 if (old) { 1344 is_extension_installed = true; 1345 int version_compare_result = 1346 extension->version()->CompareTo(*(old->version())); 1347 is_extension_upgrade = version_compare_result > 0; 1348 // Other than for unpacked extensions, CrxInstaller should have guaranteed 1349 // that we aren't downgrading. 1350 if (!Manifest::IsUnpackedLocation(extension->location())) 1351 CHECK_GE(version_compare_result, 0); 1352 } 1353 system_->runtime_data()->SetBeingUpgraded(extension, is_extension_upgrade); 1354 1355 // The extension is now loaded, remove its data from unloaded extension map. 1356 unloaded_extension_paths_.erase(extension->id()); 1357 1358 // If a terminated extension is loaded, remove it from the terminated list. 1359 UntrackTerminatedExtension(extension->id()); 1360 1361 // If the extension was disabled for a reload, then enable it. 1362 bool reloading = reloading_extensions_.erase(extension->id()) > 0; 1363 1364 // Check if the extension's privileges have changed and mark the 1365 // extension disabled if necessary. 1366 CheckPermissionsIncrease(extension, is_extension_installed); 1367 1368 if (is_extension_installed && !reloading) { 1369 // To upgrade an extension in place, unload the old one and then load the 1370 // new one. ReloadExtension disables the extension, which is sufficient. 1371 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); 1372 } 1373 1374 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { 1375 // Only prefs is checked for the blacklist. We rely on callers to check the 1376 // blacklist before calling into here, e.g. CrxInstaller checks before 1377 // installation then threads through the install and pending install flow 1378 // of this class, and we check when loading installed extensions. 1379 registry_->AddBlacklisted(extension); 1380 } else if (!reloading && 1381 extension_prefs_->IsExtensionDisabled(extension->id())) { 1382 registry_->AddDisabled(extension); 1383 if (extension_sync_service_) 1384 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1385 content::NotificationService::current()->Notify( 1386 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, 1387 content::Source<Profile>(profile_), 1388 content::Details<const Extension>(extension)); 1389 1390 // Show the extension disabled error if a permissions increase or a remote 1391 // installation is the reason it was disabled, and no other reasons exist. 1392 int reasons = extension_prefs_->GetDisableReasons(extension->id()); 1393 const int kReasonMask = Extension::DISABLE_PERMISSIONS_INCREASE | 1394 Extension::DISABLE_REMOTE_INSTALL; 1395 if (reasons & kReasonMask && !(reasons & ~kReasonMask)) { 1396 extensions::AddExtensionDisabledError( 1397 this, 1398 extension, 1399 extension_prefs_->HasDisableReason( 1400 extension->id(), Extension::DISABLE_REMOTE_INSTALL)); 1401 } 1402 } else if (reloading) { 1403 // Replace the old extension with the new version. 1404 CHECK(!registry_->AddDisabled(extension)); 1405 EnableExtension(extension->id()); 1406 } else { 1407 // All apps that are displayed in the launcher are ordered by their ordinals 1408 // so we must ensure they have valid ordinals. 1409 if (extension->RequiresSortOrdinal()) { 1410 extension_prefs_->app_sorting()->SetExtensionVisible( 1411 extension->id(), 1412 extension->ShouldDisplayInNewTabPage() && 1413 !extension_prefs_->IsEphemeralApp(extension->id())); 1414 if (!extension_prefs_->IsEphemeralApp(extension->id())) { 1415 extension_prefs_->app_sorting()->EnsureValidOrdinals( 1416 extension->id(), syncer::StringOrdinal()); 1417 } 1418 } 1419 1420 registry_->AddEnabled(extension); 1421 if (extension_sync_service_) 1422 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1423 NotifyExtensionLoaded(extension); 1424 } 1425 system_->runtime_data()->SetBeingUpgraded(extension, false); 1426 } 1427 1428 void ExtensionService::AddComponentExtension(const Extension* extension) { 1429 const std::string old_version_string( 1430 extension_prefs_->GetVersionString(extension->id())); 1431 const Version old_version(old_version_string); 1432 1433 VLOG(1) << "AddComponentExtension " << extension->name(); 1434 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { 1435 VLOG(1) << "Component extension " << extension->name() << " (" 1436 << extension->id() << ") installing/upgrading from '" 1437 << old_version_string << "' to " << extension->version()->GetString(); 1438 1439 AddNewOrUpdatedExtension(extension, 1440 Extension::ENABLED, 1441 extensions::kInstallFlagNone, 1442 syncer::StringOrdinal(), 1443 std::string()); 1444 return; 1445 } 1446 1447 AddExtension(extension); 1448 } 1449 1450 void ExtensionService::CheckPermissionsIncrease(const Extension* extension, 1451 bool is_extension_installed) { 1452 extensions::PermissionsUpdater(profile_).InitializePermissions(extension); 1453 1454 // We keep track of all permissions the user has granted each extension. 1455 // This allows extensions to gracefully support backwards compatibility 1456 // by including unknown permissions in their manifests. When the user 1457 // installs the extension, only the recognized permissions are recorded. 1458 // When the unknown permissions become recognized (e.g., through browser 1459 // upgrade), we can prompt the user to accept these new permissions. 1460 // Extensions can also silently upgrade to less permissions, and then 1461 // silently upgrade to a version that adds these permissions back. 1462 // 1463 // For example, pretend that Chrome 10 includes a permission "omnibox" 1464 // for an API that adds suggestions to the omnibox. An extension can 1465 // maintain backwards compatibility while still having "omnibox" in the 1466 // manifest. If a user installs the extension on Chrome 9, the browser 1467 // will record the permissions it recognized, not including "omnibox." 1468 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome 1469 // will disable the extension and prompt the user to approve the increase 1470 // in privileges. The extension could then release a new version that 1471 // removes the "omnibox" permission. When the user upgrades, Chrome will 1472 // still remember that "omnibox" had been granted, so that if the 1473 // extension once again includes "omnibox" in an upgrade, the extension 1474 // can upgrade without requiring this user's approval. 1475 int disable_reasons = extension_prefs_->GetDisableReasons(extension->id()); 1476 1477 bool auto_grant_permission = 1478 (!is_extension_installed && extension->was_installed_by_default()) || 1479 extensions::ExtensionsBrowserClient::Get()->IsRunningInForcedAppMode(); 1480 // Silently grant all active permissions to default apps only on install. 1481 // After install they should behave like other apps. 1482 // Silently grant all active permissions to apps install in kiosk mode on both 1483 // install and update. 1484 if (auto_grant_permission) 1485 GrantPermissions(extension); 1486 1487 bool is_privilege_increase = false; 1488 // We only need to compare the granted permissions to the current permissions 1489 // if the extension is not allowed to silently increase its permissions. 1490 if (!extensions::PermissionsData::CanSilentlyIncreasePermissions(extension) && 1491 !auto_grant_permission) { 1492 // Add all the recognized permissions if the granted permissions list 1493 // hasn't been initialized yet. 1494 scoped_refptr<PermissionSet> granted_permissions = 1495 extension_prefs_->GetGrantedPermissions(extension->id()); 1496 CHECK(granted_permissions.get()); 1497 1498 // Here, we check if an extension's privileges have increased in a manner 1499 // that requires the user's approval. This could occur because the browser 1500 // upgraded and recognized additional privileges, or an extension upgrades 1501 // to a version that requires additional privileges. 1502 is_privilege_increase = 1503 extensions::PermissionMessageProvider::Get()->IsPrivilegeIncrease( 1504 granted_permissions.get(), 1505 extension->permissions_data()->active_permissions().get(), 1506 extension->GetType()); 1507 } 1508 1509 if (is_extension_installed) { 1510 // If the extension was already disabled, suppress any alerts for becoming 1511 // disabled on permissions increase. 1512 bool previously_disabled = 1513 extension_prefs_->IsExtensionDisabled(extension->id()); 1514 // Legacy disabled extensions do not have a disable reason. Infer that if 1515 // there was no permission increase, it was likely disabled by the user. 1516 if (previously_disabled && disable_reasons == Extension::DISABLE_NONE && 1517 !extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { 1518 disable_reasons |= Extension::DISABLE_USER_ACTION; 1519 } 1520 // Extensions that came to us disabled from sync need a similar inference, 1521 // except based on the new version's permissions. 1522 if (previously_disabled && 1523 disable_reasons == Extension::DISABLE_UNKNOWN_FROM_SYNC) { 1524 // Remove the DISABLE_UNKNOWN_FROM_SYNC reason. 1525 extension_prefs_->ClearDisableReasons(extension->id()); 1526 if (!is_privilege_increase) 1527 disable_reasons |= Extension::DISABLE_USER_ACTION; 1528 } 1529 disable_reasons &= ~Extension::DISABLE_UNKNOWN_FROM_SYNC; 1530 } 1531 1532 // Extension has changed permissions significantly. Disable it. A 1533 // notification should be sent by the caller. If the extension is already 1534 // disabled because it was installed remotely, don't add another disable 1535 // reason, but instead always set the "did escalate permissions" flag, to 1536 // ensure enabling it will always show a warning. 1537 if (disable_reasons == Extension::DISABLE_REMOTE_INSTALL) { 1538 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); 1539 } else if (is_privilege_increase) { 1540 disable_reasons |= Extension::DISABLE_PERMISSIONS_INCREASE; 1541 if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { 1542 RecordPermissionMessagesHistogram(extension, 1543 "Extensions.Permissions_AutoDisable2"); 1544 } 1545 extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); 1546 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); 1547 } 1548 if (disable_reasons != Extension::DISABLE_NONE) { 1549 extension_prefs_->AddDisableReason( 1550 extension->id(), 1551 static_cast<Extension::DisableReason>(disable_reasons)); 1552 } 1553 } 1554 1555 void ExtensionService::UpdateActiveExtensionsInCrashReporter() { 1556 std::set<std::string> extension_ids; 1557 const ExtensionSet& extensions = registry_->enabled_extensions(); 1558 for (ExtensionSet::const_iterator iter = extensions.begin(); 1559 iter != extensions.end(); ++iter) { 1560 const Extension* extension = iter->get(); 1561 if (!extension->is_theme() && extension->location() != Manifest::COMPONENT) 1562 extension_ids.insert(extension->id()); 1563 } 1564 1565 // TODO(kalman): This is broken. ExtensionService is per-profile. 1566 // crash_keys::SetActiveExtensions is per-process. See 1567 // http://crbug.com/355029. 1568 crash_keys::SetActiveExtensions(extension_ids); 1569 } 1570 1571 void ExtensionService::OnExtensionInstalled( 1572 const Extension* extension, 1573 const syncer::StringOrdinal& page_ordinal, 1574 int install_flags) { 1575 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1576 1577 const std::string& id = extension->id(); 1578 bool initial_enable = ShouldEnableOnInstall(extension); 1579 std::string install_parameter; 1580 const extensions::PendingExtensionInfo* pending_extension_info = 1581 pending_extension_manager()->GetById(id); 1582 if (pending_extension_info) { 1583 if (!pending_extension_info->ShouldAllowInstall(extension)) { 1584 pending_extension_manager()->Remove(id); 1585 1586 LOG(WARNING) << "ShouldAllowInstall() returned false for " 1587 << id << " of type " << extension->GetType() 1588 << " and update URL " 1589 << extensions::ManifestURL::GetUpdateURL(extension).spec() 1590 << "; not installing"; 1591 1592 // Delete the extension directory since we're not going to 1593 // load it. 1594 if (!GetFileTaskRunner()->PostTask( 1595 FROM_HERE, 1596 base::Bind(&extensions::file_util::DeleteFile, 1597 extension->path(), 1598 true))) { 1599 NOTREACHED(); 1600 } 1601 return; 1602 } 1603 1604 install_parameter = pending_extension_info->install_parameter(); 1605 pending_extension_manager()->Remove(id); 1606 } else { 1607 // We explicitly want to re-enable an uninstalled external 1608 // extension; if we're here, that means the user is manually 1609 // installing the extension. 1610 if (extension_prefs_->IsExternalExtensionUninstalled(id)) { 1611 initial_enable = true; 1612 } 1613 } 1614 1615 // Unsupported requirements overrides the management policy. 1616 if (install_flags & extensions::kInstallFlagHasRequirementErrors) { 1617 initial_enable = false; 1618 extension_prefs_->AddDisableReason( 1619 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); 1620 // If the extension was disabled because of unsupported requirements but 1621 // now supports all requirements after an update and there are not other 1622 // disable reasons, enable it. 1623 } else if (extension_prefs_->GetDisableReasons(id) == 1624 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { 1625 initial_enable = true; 1626 extension_prefs_->ClearDisableReasons(id); 1627 } 1628 1629 if (install_flags & extensions::kInstallFlagIsBlacklistedForMalware) { 1630 // Installation of a blacklisted extension can happen from sync, policy, 1631 // etc, where to maintain consistency we need to install it, just never 1632 // load it (see AddExtension). Usually it should be the job of callers to 1633 // incercept blacklisted extension earlier (e.g. CrxInstaller, before even 1634 // showing the install dialogue). 1635 extension_prefs_->AcknowledgeBlacklistedExtension(id); 1636 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", 1637 extension->location(), 1638 Manifest::NUM_LOCATIONS); 1639 } 1640 1641 if (!GetInstalledExtension(extension->id())) { 1642 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", 1643 extension->GetType(), 100); 1644 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", 1645 extension->location(), Manifest::NUM_LOCATIONS); 1646 RecordPermissionMessagesHistogram(extension, 1647 "Extensions.Permissions_Install2"); 1648 } else { 1649 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", 1650 extension->GetType(), 100); 1651 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", 1652 extension->location(), Manifest::NUM_LOCATIONS); 1653 1654 // A fully installed app cannot be demoted to an ephemeral app. 1655 if ((install_flags & extensions::kInstallFlagIsEphemeral) && 1656 !extension_prefs_->IsEphemeralApp(id)) { 1657 install_flags &= ~static_cast<int>(extensions::kInstallFlagIsEphemeral); 1658 } 1659 } 1660 1661 const Extension::State initial_state = 1662 initial_enable ? Extension::ENABLED : Extension::DISABLED; 1663 if (ShouldDelayExtensionUpdate( 1664 id, 1665 !!(install_flags & extensions::kInstallFlagInstallImmediately))) { 1666 extension_prefs_->SetDelayedInstallInfo( 1667 extension, 1668 initial_state, 1669 install_flags, 1670 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, 1671 page_ordinal, 1672 install_parameter); 1673 1674 // Transfer ownership of |extension|. 1675 delayed_installs_.Insert(extension); 1676 1677 // Notify observers that app update is available. 1678 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, 1679 OnAppUpdateAvailable(extension)); 1680 return; 1681 } 1682 1683 extensions::SharedModuleService::ImportStatus status = 1684 shared_module_service_->SatisfyImports(extension); 1685 if (installs_delayed_for_gc_) { 1686 extension_prefs_->SetDelayedInstallInfo( 1687 extension, 1688 initial_state, 1689 install_flags, 1690 extensions::ExtensionPrefs::DELAY_REASON_GC, 1691 page_ordinal, 1692 install_parameter); 1693 delayed_installs_.Insert(extension); 1694 } else if (status != SharedModuleService::IMPORT_STATUS_OK) { 1695 if (status == SharedModuleService::IMPORT_STATUS_UNSATISFIED) { 1696 extension_prefs_->SetDelayedInstallInfo( 1697 extension, 1698 initial_state, 1699 install_flags, 1700 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS, 1701 page_ordinal, 1702 install_parameter); 1703 delayed_installs_.Insert(extension); 1704 } 1705 } else { 1706 AddNewOrUpdatedExtension(extension, 1707 initial_state, 1708 install_flags, 1709 page_ordinal, 1710 install_parameter); 1711 } 1712 } 1713 1714 void ExtensionService::OnExtensionManagementSettingsChanged() { 1715 error_controller_->ShowErrorIfNeeded(); 1716 CheckManagementPolicy(); 1717 } 1718 1719 void ExtensionService::AddNewOrUpdatedExtension( 1720 const Extension* extension, 1721 Extension::State initial_state, 1722 int install_flags, 1723 const syncer::StringOrdinal& page_ordinal, 1724 const std::string& install_parameter) { 1725 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1726 bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); 1727 extension_prefs_->OnExtensionInstalled( 1728 extension, initial_state, page_ordinal, install_flags, install_parameter); 1729 delayed_installs_.Remove(extension->id()); 1730 if (InstallVerifier::NeedsVerification(*extension)) 1731 system_->install_verifier()->VerifyExtension(extension->id()); 1732 FinishInstallation(extension, was_ephemeral); 1733 } 1734 1735 void ExtensionService::MaybeFinishDelayedInstallation( 1736 const std::string& extension_id) { 1737 // Check if the extension already got installed. 1738 if (!delayed_installs_.Contains(extension_id)) 1739 return; 1740 extensions::ExtensionPrefs::DelayReason reason = 1741 extension_prefs_->GetDelayedInstallReason(extension_id); 1742 1743 // Check if the extension is idle. DELAY_REASON_NONE is used for older 1744 // preferences files that will not have set this field but it was previously 1745 // only used for idle updates. 1746 if ((reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE || 1747 reason == extensions::ExtensionPrefs::DELAY_REASON_NONE) && 1748 is_ready() && !extensions::util::IsExtensionIdle(extension_id, profile_)) 1749 return; 1750 1751 const Extension* extension = delayed_installs_.GetByID(extension_id); 1752 if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS) { 1753 extensions::SharedModuleService::ImportStatus status = 1754 shared_module_service_->SatisfyImports(extension); 1755 if (status != SharedModuleService::IMPORT_STATUS_OK) { 1756 if (status == SharedModuleService::IMPORT_STATUS_UNRECOVERABLE) { 1757 delayed_installs_.Remove(extension_id); 1758 // Make sure no version of the extension is actually installed, (i.e., 1759 // that this delayed install was not an update). 1760 CHECK(!extension_prefs_->GetInstalledExtensionInfo(extension_id).get()); 1761 extension_prefs_->DeleteExtensionPrefs(extension_id); 1762 } 1763 return; 1764 } 1765 } 1766 1767 FinishDelayedInstallation(extension_id); 1768 } 1769 1770 void ExtensionService::FinishDelayedInstallation( 1771 const std::string& extension_id) { 1772 scoped_refptr<const Extension> extension( 1773 GetPendingExtensionUpdate(extension_id)); 1774 CHECK(extension.get()); 1775 delayed_installs_.Remove(extension_id); 1776 1777 bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); 1778 if (!extension_prefs_->FinishDelayedInstallInfo(extension_id)) 1779 NOTREACHED(); 1780 1781 FinishInstallation(extension.get(), was_ephemeral); 1782 } 1783 1784 void ExtensionService::FinishInstallation( 1785 const Extension* extension, bool was_ephemeral) { 1786 const extensions::Extension* existing_extension = 1787 GetInstalledExtension(extension->id()); 1788 bool is_update = false; 1789 std::string old_name; 1790 if (existing_extension) { 1791 is_update = true; 1792 old_name = existing_extension->name(); 1793 } 1794 bool from_ephemeral = 1795 was_ephemeral && !extension_prefs_->IsEphemeralApp(extension->id()); 1796 extensions::InstalledExtensionInfo details( 1797 extension, is_update, from_ephemeral, old_name); 1798 content::NotificationService::current()->Notify( 1799 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, 1800 content::Source<Profile>(profile_), 1801 content::Details<const extensions::InstalledExtensionInfo>(&details)); 1802 1803 registry_->TriggerOnWillBeInstalled( 1804 extension, is_update, from_ephemeral, old_name); 1805 1806 // Unpacked extensions default to allowing file access, but if that has been 1807 // overridden, don't reset the value. 1808 if (Manifest::ShouldAlwaysAllowFileAccess(extension->location()) && 1809 !extension_prefs_->HasAllowFileAccessSetting(extension->id())) { 1810 extension_prefs_->SetAllowFileAccess(extension->id(), true); 1811 } 1812 1813 AddExtension(extension); 1814 1815 // Notify observers that need to know when an installation is complete. 1816 registry_->TriggerOnInstalled(extension, is_update); 1817 1818 // Check extensions that may have been delayed only because this shared module 1819 // was not available. 1820 if (SharedModuleInfo::IsSharedModule(extension)) 1821 MaybeFinishDelayedInstallations(); 1822 } 1823 1824 void ExtensionService::PromoteEphemeralApp( 1825 const extensions::Extension* extension, bool is_from_sync) { 1826 DCHECK(GetInstalledExtension(extension->id()) && 1827 extension_prefs_->IsEphemeralApp(extension->id())); 1828 1829 if (extension->RequiresSortOrdinal()) { 1830 extension_prefs_->app_sorting()->SetExtensionVisible( 1831 extension->id(), extension->ShouldDisplayInNewTabPage()); 1832 1833 if (!is_from_sync) { 1834 // Reset the sort ordinals of the app to ensure it is added to the default 1835 // position, like newly installed apps would. 1836 extension_prefs_->app_sorting()->ClearOrdinals(extension->id()); 1837 } 1838 1839 extension_prefs_->app_sorting()->EnsureValidOrdinals( 1840 extension->id(), syncer::StringOrdinal()); 1841 } 1842 1843 // Remove the ephemeral flags from the preferences. 1844 extension_prefs_->OnEphemeralAppPromoted(extension->id()); 1845 1846 // Fire install-related events to allow observers to handle the promotion 1847 // of the ephemeral app. 1848 extensions::InstalledExtensionInfo details( 1849 extension, 1850 true /* is update */, 1851 true /* from ephemeral */, 1852 extension->name() /* old name */); 1853 content::NotificationService::current()->Notify( 1854 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, 1855 content::Source<Profile>(profile_), 1856 content::Details<const extensions::InstalledExtensionInfo>(&details)); 1857 1858 registry_->TriggerOnWillBeInstalled( 1859 extension, 1860 true /* is update */, 1861 true /* from ephemeral */, 1862 extension->name() /* old name */); 1863 1864 if (registry_->enabled_extensions().Contains(extension->id())) { 1865 // If the app is already enabled and loaded, fire the load events to allow 1866 // observers to handle the promotion of the ephemeral app. 1867 content::NotificationService::current()->Notify( 1868 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 1869 content::Source<Profile>(profile_), 1870 content::Details<const Extension>(extension)); 1871 1872 registry_->TriggerOnLoaded(extension); 1873 } else { 1874 // Cached ephemeral apps may be updated and disabled due to permissions 1875 // increase. The app can be enabled (as long as no other disable reasons 1876 // exist) as the install was user-acknowledged. 1877 int disable_mask = Extension::DISABLE_NONE; 1878 if (!is_from_sync) 1879 disable_mask |= Extension::DISABLE_PERMISSIONS_INCREASE; 1880 1881 int other_disable_reasons = 1882 extension_prefs_->GetDisableReasons(extension->id()) & ~disable_mask; 1883 if (!other_disable_reasons) { 1884 if (extension_prefs_->DidExtensionEscalatePermissions(extension->id())) 1885 GrantPermissionsAndEnableExtension(extension); 1886 else 1887 EnableExtension(extension->id()); 1888 } 1889 } 1890 1891 registry_->TriggerOnInstalled(extension, true); 1892 1893 if (!is_from_sync && extension_sync_service_) 1894 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1895 } 1896 1897 const Extension* ExtensionService::GetPendingExtensionUpdate( 1898 const std::string& id) const { 1899 return delayed_installs_.GetByID(id); 1900 } 1901 1902 void ExtensionService::RegisterContentSettings( 1903 HostContentSettingsMap* host_content_settings_map) { 1904 host_content_settings_map->RegisterProvider( 1905 HostContentSettingsMap::INTERNAL_EXTENSION_PROVIDER, 1906 scoped_ptr<content_settings::ObservableProvider>( 1907 new content_settings::InternalExtensionProvider(this))); 1908 1909 host_content_settings_map->RegisterProvider( 1910 HostContentSettingsMap::CUSTOM_EXTENSION_PROVIDER, 1911 scoped_ptr<content_settings::ObservableProvider>( 1912 new content_settings::CustomExtensionProvider( 1913 extensions::ContentSettingsService::Get( 1914 profile_)->content_settings_store(), 1915 profile_->GetOriginalProfile() != profile_))); 1916 } 1917 1918 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { 1919 // No need to check for duplicates; inserting a duplicate is a no-op. 1920 registry_->AddTerminated(make_scoped_refptr(extension)); 1921 extensions_being_terminated_.erase(extension->id()); 1922 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_TERMINATE); 1923 } 1924 1925 void ExtensionService::TerminateExtension(const std::string& extension_id) { 1926 const Extension* extension = GetInstalledExtension(extension_id); 1927 TrackTerminatedExtension(extension); 1928 } 1929 1930 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { 1931 std::string lowercase_id = base::StringToLowerASCII(id); 1932 const Extension* extension = 1933 registry_->terminated_extensions().GetByID(lowercase_id); 1934 registry_->RemoveTerminated(lowercase_id); 1935 if (extension) { 1936 content::NotificationService::current()->Notify( 1937 extensions::NOTIFICATION_EXTENSION_REMOVED, 1938 content::Source<Profile>(profile_), 1939 content::Details<const Extension>(extension)); 1940 } 1941 } 1942 1943 const Extension* ExtensionService::GetInstalledExtension( 1944 const std::string& id) const { 1945 return registry_->GetExtensionById(id, ExtensionRegistry::EVERYTHING); 1946 } 1947 1948 bool ExtensionService::OnExternalExtensionFileFound( 1949 const std::string& id, 1950 const Version* version, 1951 const base::FilePath& path, 1952 Manifest::Location location, 1953 int creation_flags, 1954 bool mark_acknowledged) { 1955 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1956 CHECK(crx_file::id_util::IdIsValid(id)); 1957 if (extension_prefs_->IsExternalExtensionUninstalled(id)) 1958 return false; 1959 1960 // Before even bothering to unpack, check and see if we already have this 1961 // version. This is important because these extensions are going to get 1962 // installed on every startup. 1963 const Extension* existing = GetExtensionById(id, true); 1964 1965 if (existing) { 1966 // The default apps will have the location set as INTERNAL. Since older 1967 // default apps are installed as EXTERNAL, we override them. However, if the 1968 // app is already installed as internal, then do the version check. 1969 // TODO(grv) : Remove after Q1-2013. 1970 bool is_default_apps_migration = 1971 (location == Manifest::INTERNAL && 1972 Manifest::IsExternalLocation(existing->location())); 1973 1974 if (!is_default_apps_migration) { 1975 DCHECK(version); 1976 1977 switch (existing->version()->CompareTo(*version)) { 1978 case -1: // existing version is older, we should upgrade 1979 break; 1980 case 0: // existing version is same, do nothing 1981 return false; 1982 case 1: // existing version is newer, uh-oh 1983 LOG(WARNING) << "Found external version of extension " << id 1984 << "that is older than current version. Current version " 1985 << "is: " << existing->VersionString() << ". New " 1986 << "version is: " << version->GetString() 1987 << ". Keeping current version."; 1988 return false; 1989 } 1990 } 1991 } 1992 1993 // If the extension is already pending, don't start an install. 1994 if (!pending_extension_manager()->AddFromExternalFile( 1995 id, location, *version, creation_flags, mark_acknowledged)) { 1996 return false; 1997 } 1998 1999 // no client (silent install) 2000 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(this)); 2001 installer->set_install_source(location); 2002 installer->set_expected_id(id); 2003 installer->set_expected_version(*version); 2004 installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE); 2005 installer->set_creation_flags(creation_flags); 2006 #if defined(OS_CHROMEOS) 2007 extensions::InstallLimiter::Get(profile_)->Add(installer, path); 2008 #else 2009 installer->InstallCrx(path); 2010 #endif 2011 2012 // Depending on the source, a new external extension might not need a user 2013 // notification on installation. For such extensions, mark them acknowledged 2014 // now to suppress the notification. 2015 if (mark_acknowledged) 2016 external_install_manager_->AcknowledgeExternalExtension(id); 2017 2018 return true; 2019 } 2020 2021 void ExtensionService::DidCreateRenderViewForBackgroundPage( 2022 extensions::ExtensionHost* host) { 2023 OrphanedDevTools::iterator iter = 2024 orphaned_dev_tools_.find(host->extension_id()); 2025 if (iter == orphaned_dev_tools_.end()) 2026 return; 2027 2028 iter->second->ConnectWebContents(host->host_contents()); 2029 orphaned_dev_tools_.erase(iter); 2030 } 2031 2032 void ExtensionService::Observe(int type, 2033 const content::NotificationSource& source, 2034 const content::NotificationDetails& details) { 2035 switch (type) { 2036 case chrome::NOTIFICATION_APP_TERMINATING: 2037 // Shutdown has started. Don't start any more extension installs. 2038 // (We cannot use ExtensionService::Shutdown() for this because it 2039 // happens too late in browser teardown.) 2040 browser_terminating_ = true; 2041 break; 2042 case extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: { 2043 if (profile_ != 2044 content::Source<Profile>(source).ptr()->GetOriginalProfile()) { 2045 break; 2046 } 2047 2048 extensions::ExtensionHost* host = 2049 content::Details<extensions::ExtensionHost>(details).ptr(); 2050 2051 // If the extension is already being terminated, there is nothing left to 2052 // do. 2053 if (!extensions_being_terminated_.insert(host->extension_id()).second) 2054 break; 2055 2056 // Mark the extension as terminated and Unload it. We want it to 2057 // be in a consistent state: either fully working or not loaded 2058 // at all, but never half-crashed. We do it in a PostTask so 2059 // that other handlers of this notification will still have 2060 // access to the Extension and ExtensionHost. 2061 base::MessageLoop::current()->PostTask( 2062 FROM_HERE, 2063 base::Bind( 2064 &ExtensionService::TrackTerminatedExtension, 2065 AsWeakPtr(), 2066 host->extension())); 2067 break; 2068 } 2069 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { 2070 content::RenderProcessHost* process = 2071 content::Source<content::RenderProcessHost>(source).ptr(); 2072 Profile* host_profile = 2073 Profile::FromBrowserContext(process->GetBrowserContext()); 2074 if (!profile_->IsSameProfile(host_profile->GetOriginalProfile())) 2075 break; 2076 2077 extensions::ProcessMap* process_map = 2078 extensions::ProcessMap::Get(profile_); 2079 if (process_map->Contains(process->GetID())) { 2080 // An extension process was terminated, this might have resulted in an 2081 // app or extension becoming idle. 2082 std::set<std::string> extension_ids = 2083 process_map->GetExtensionsInProcess(process->GetID()); 2084 for (std::set<std::string>::const_iterator it = extension_ids.begin(); 2085 it != extension_ids.end(); ++it) { 2086 if (delayed_installs_.Contains(*it)) { 2087 base::MessageLoop::current()->PostDelayedTask( 2088 FROM_HERE, 2089 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, 2090 AsWeakPtr(), *it), 2091 base::TimeDelta::FromSeconds(kUpdateIdleDelay)); 2092 } 2093 } 2094 } 2095 2096 process_map->RemoveAllFromProcess(process->GetID()); 2097 BrowserThread::PostTask( 2098 BrowserThread::IO, 2099 FROM_HERE, 2100 base::Bind(&extensions::InfoMap::UnregisterAllExtensionsInProcess, 2101 system_->info_map(), 2102 process->GetID())); 2103 break; 2104 } 2105 case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { 2106 // Notify observers that chrome update is available. 2107 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, 2108 OnChromeUpdateAvailable()); 2109 break; 2110 } 2111 case chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED: { 2112 OnProfileDestructionStarted(); 2113 break; 2114 } 2115 2116 default: 2117 NOTREACHED() << "Unexpected notification type."; 2118 } 2119 } 2120 2121 bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) { 2122 // Extensions installed by policy can't be disabled. So even if a previous 2123 // installation disabled the extension, make sure it is now enabled. 2124 if (system_->management_policy()->MustRemainEnabled(extension, NULL)) 2125 return true; 2126 2127 if (extension_prefs_->IsExtensionDisabled(extension->id())) 2128 return false; 2129 2130 if (FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) { 2131 // External extensions are initially disabled. We prompt the user before 2132 // enabling them. Hosted apps are excepted because they are not dangerous 2133 // (they need to be launched by the user anyway). 2134 if (extension->GetType() != Manifest::TYPE_HOSTED_APP && 2135 Manifest::IsExternalLocation(extension->location()) && 2136 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { 2137 return false; 2138 } 2139 } 2140 2141 return true; 2142 } 2143 2144 bool ExtensionService::ShouldDelayExtensionUpdate( 2145 const std::string& extension_id, 2146 bool install_immediately) const { 2147 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; 2148 2149 // If delayed updates are globally disabled, or just for this extension, 2150 // don't delay. 2151 if (!install_updates_when_idle_ || install_immediately) 2152 return false; 2153 2154 const Extension* old = GetInstalledExtension(extension_id); 2155 // If there is no old extension, this is not an update, so don't delay. 2156 if (!old) 2157 return false; 2158 2159 if (extensions::BackgroundInfo::HasPersistentBackgroundPage(old)) { 2160 // Delay installation if the extension listens for the onUpdateAvailable 2161 // event. 2162 return system_->event_router()->ExtensionHasEventListener( 2163 extension_id, kOnUpdateAvailableEvent); 2164 } else { 2165 // Delay installation if the extension is not idle. 2166 return !extensions::util::IsExtensionIdle(extension_id, profile_); 2167 } 2168 } 2169 2170 void ExtensionService::OnGarbageCollectIsolatedStorageStart() { 2171 DCHECK(!installs_delayed_for_gc_); 2172 installs_delayed_for_gc_ = true; 2173 } 2174 2175 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { 2176 DCHECK(installs_delayed_for_gc_); 2177 installs_delayed_for_gc_ = false; 2178 MaybeFinishDelayedInstallations(); 2179 } 2180 2181 void ExtensionService::MaybeFinishDelayedInstallations() { 2182 std::vector<std::string> to_be_installed; 2183 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); 2184 it != delayed_installs_.end(); 2185 ++it) { 2186 to_be_installed.push_back((*it)->id()); 2187 } 2188 for (std::vector<std::string>::const_iterator it = to_be_installed.begin(); 2189 it != to_be_installed.end(); 2190 ++it) { 2191 MaybeFinishDelayedInstallation(*it); 2192 } 2193 } 2194 2195 void ExtensionService::OnBlacklistUpdated() { 2196 blacklist_->GetBlacklistedIDs( 2197 registry_->GenerateInstalledExtensionsSet()->GetIDs(), 2198 base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr())); 2199 } 2200 2201 void ExtensionService::ManageBlacklist( 2202 const extensions::Blacklist::BlacklistStateMap& state_map) { 2203 DCHECK_CURRENTLY_ON(BrowserThread::UI); 2204 2205 std::set<std::string> blocked; 2206 ExtensionIdSet greylist; 2207 ExtensionIdSet unchanged; 2208 for (extensions::Blacklist::BlacklistStateMap::const_iterator it = 2209 state_map.begin(); 2210 it != state_map.end(); 2211 ++it) { 2212 switch (it->second) { 2213 case extensions::NOT_BLACKLISTED: 2214 break; 2215 2216 case extensions::BLACKLISTED_MALWARE: 2217 blocked.insert(it->first); 2218 break; 2219 2220 case extensions::BLACKLISTED_SECURITY_VULNERABILITY: 2221 case extensions::BLACKLISTED_CWS_POLICY_VIOLATION: 2222 case extensions::BLACKLISTED_POTENTIALLY_UNWANTED: 2223 greylist.insert(it->first); 2224 break; 2225 2226 case extensions::BLACKLISTED_UNKNOWN: 2227 unchanged.insert(it->first); 2228 break; 2229 } 2230 } 2231 2232 UpdateBlockedExtensions(blocked, unchanged); 2233 UpdateGreylistedExtensions(greylist, unchanged, state_map); 2234 2235 error_controller_->ShowErrorIfNeeded(); 2236 } 2237 2238 namespace { 2239 void Partition(const ExtensionIdSet& before, 2240 const ExtensionIdSet& after, 2241 const ExtensionIdSet& unchanged, 2242 ExtensionIdSet* no_longer, 2243 ExtensionIdSet* not_yet) { 2244 *not_yet = base::STLSetDifference<ExtensionIdSet>(after, before); 2245 *no_longer = base::STLSetDifference<ExtensionIdSet>(before, after); 2246 *no_longer = base::STLSetDifference<ExtensionIdSet>(*no_longer, unchanged); 2247 } 2248 } // namespace 2249 2250 void ExtensionService::UpdateBlockedExtensions( 2251 const ExtensionIdSet& blocked, 2252 const ExtensionIdSet& unchanged) { 2253 ExtensionIdSet not_yet_blocked, no_longer_blocked; 2254 Partition(registry_->blacklisted_extensions().GetIDs(), 2255 blocked, unchanged, 2256 &no_longer_blocked, ¬_yet_blocked); 2257 2258 for (ExtensionIdSet::iterator it = no_longer_blocked.begin(); 2259 it != no_longer_blocked.end(); ++it) { 2260 scoped_refptr<const Extension> extension = 2261 registry_->blacklisted_extensions().GetByID(*it); 2262 if (!extension.get()) { 2263 NOTREACHED() << "Extension " << *it << " no longer blocked, " 2264 << "but it was never blocked."; 2265 continue; 2266 } 2267 registry_->RemoveBlacklisted(*it); 2268 extension_prefs_->SetExtensionBlacklisted(extension->id(), false); 2269 AddExtension(extension.get()); 2270 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.UnblacklistInstalled", 2271 extension->location(), 2272 Manifest::NUM_LOCATIONS); 2273 } 2274 2275 for (ExtensionIdSet::iterator it = not_yet_blocked.begin(); 2276 it != not_yet_blocked.end(); ++it) { 2277 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); 2278 if (!extension.get()) { 2279 NOTREACHED() << "Extension " << *it << " needs to be " 2280 << "blacklisted, but it's not installed."; 2281 continue; 2282 } 2283 registry_->AddBlacklisted(extension); 2284 extension_prefs_->SetExtensionBlacklistState( 2285 extension->id(), extensions::BLACKLISTED_MALWARE); 2286 UnloadExtension(*it, UnloadedExtensionInfo::REASON_BLACKLIST); 2287 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled", 2288 extension->location(), Manifest::NUM_LOCATIONS); 2289 } 2290 } 2291 2292 // TODO(oleg): UMA logging 2293 void ExtensionService::UpdateGreylistedExtensions( 2294 const ExtensionIdSet& greylist, 2295 const ExtensionIdSet& unchanged, 2296 const extensions::Blacklist::BlacklistStateMap& state_map) { 2297 ExtensionIdSet not_yet_greylisted, no_longer_greylisted; 2298 Partition(greylist_.GetIDs(), 2299 greylist, unchanged, 2300 &no_longer_greylisted, ¬_yet_greylisted); 2301 2302 for (ExtensionIdSet::iterator it = no_longer_greylisted.begin(); 2303 it != no_longer_greylisted.end(); ++it) { 2304 scoped_refptr<const Extension> extension = greylist_.GetByID(*it); 2305 if (!extension.get()) { 2306 NOTREACHED() << "Extension " << *it << " no longer greylisted, " 2307 << "but it was not marked as greylisted."; 2308 continue; 2309 } 2310 2311 greylist_.Remove(*it); 2312 extension_prefs_->SetExtensionBlacklistState(extension->id(), 2313 extensions::NOT_BLACKLISTED); 2314 if (extension_prefs_->GetDisableReasons(extension->id()) & 2315 extensions::Extension::DISABLE_GREYLIST) 2316 EnableExtension(*it); 2317 } 2318 2319 for (ExtensionIdSet::iterator it = not_yet_greylisted.begin(); 2320 it != not_yet_greylisted.end(); ++it) { 2321 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); 2322 if (!extension.get()) { 2323 NOTREACHED() << "Extension " << *it << " needs to be " 2324 << "disabled, but it's not installed."; 2325 continue; 2326 } 2327 greylist_.Insert(extension); 2328 extension_prefs_->SetExtensionBlacklistState(extension->id(), 2329 state_map.find(*it)->second); 2330 if (registry_->enabled_extensions().Contains(extension->id())) 2331 DisableExtension(*it, extensions::Extension::DISABLE_GREYLIST); 2332 } 2333 } 2334 2335 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { 2336 update_observers_.AddObserver(observer); 2337 } 2338 2339 void ExtensionService::RemoveUpdateObserver( 2340 extensions::UpdateObserver* observer) { 2341 update_observers_.RemoveObserver(observer); 2342 } 2343 2344 // Used only by test code. 2345 void ExtensionService::UnloadAllExtensionsInternal() { 2346 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); 2347 2348 registry_->ClearAll(); 2349 system_->runtime_data()->ClearAll(); 2350 2351 // TODO(erikkay) should there be a notification for this? We can't use 2352 // EXTENSION_UNLOADED since that implies that the extension has been disabled 2353 // or uninstalled. 2354 } 2355 2356 void ExtensionService::OnProfileDestructionStarted() { 2357 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); 2358 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); 2359 it != ids_to_unload.end(); 2360 ++it) { 2361 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); 2362 } 2363 } 2364