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