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