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