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