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