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